mirror of
https://github.com/openharmony/third_party_elfutils.git
synced 2026-07-01 06:41:51 -04:00
propagate from branch 'com.redhat.elfutils.disasm' (head d15b4eb794e81e477f9896fe82a74cb5ecf4514c)
to branch 'com.redhat.elfutils' (head eaacbf01f8cc89d043ec6eca9b5e35cb5c4cde06)
This commit is contained in:
@@ -1,3 +1,8 @@
|
||||
2007-12-20 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* configure.ac: Add support for --enable-debugpred.
|
||||
Update likely/unlikely macros for it.
|
||||
|
||||
2007-06-05 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* Makefile.am: Remove traces of mini builds.
|
||||
|
||||
@@ -42,6 +42,10 @@
|
||||
* sparc_retval.c: Likewise.
|
||||
* x86_64_retval.c: Likewise.
|
||||
|
||||
2007-10-31 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* Makefile.am: More dependencies for the libebl_* libraries.
|
||||
|
||||
2007-08-23 Roland McGrath <roland@redhat.com>
|
||||
|
||||
* x86_64_regs.c (x86_64_register_info): Put %rflags in "integer" set.
|
||||
|
||||
+19
-11
@@ -1,6 +1,6 @@
|
||||
## Process this file with automake to create Makefile.in
|
||||
##
|
||||
## Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Red Hat, Inc.
|
||||
## Copyright (C) 2000-2006, 2007 Red Hat, Inc.
|
||||
## This file is part of Red Hat elfutils.
|
||||
##
|
||||
## Red Hat elfutils is free software; you can redistribute it and/or modify
|
||||
@@ -32,7 +32,7 @@ AM_CFLAGS =
|
||||
endif
|
||||
AM_CFLAGS += -fpic -Wall -Wshadow -Werror -Wunused -Wextra -Wformat=2 \
|
||||
-std=gnu99
|
||||
INCLUDES = -I$(srcdir) -I$(top_srcdir)/libebl \
|
||||
INCLUDES = -I$(srcdir) -I$(top_srcdir)/libebl -I$(top_srcdir)/libasm \
|
||||
-I$(top_srcdir)/libelf -I$(top_srcdir)/libdw \
|
||||
-I$(top_srcdir)/lib -I..
|
||||
|
||||
@@ -59,18 +59,10 @@ endif
|
||||
|
||||
textrel_check = if readelf -d $@ | fgrep -q TEXTREL; then exit 1; fi
|
||||
|
||||
libebl_%.so: libebl_%_pic.a libebl_%.map $(libelf) $(libdw)
|
||||
$(LINK) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \
|
||||
-Wl,--version-script,$(word 2,$^) \
|
||||
-Wl,-z,defs -Wl,--as-needed $(libelf) $(libdw) $(libmudflap)
|
||||
$(textrel_check)
|
||||
|
||||
libebl_%.map: Makefile
|
||||
echo 'ELFUTILS_$(PACKAGE_VERSION) { global: $*_init; local: *; };' > $@
|
||||
|
||||
|
||||
i386_SRCS = i386_init.c i386_symbol.c i386_corenote.c \
|
||||
i386_retval.c i386_regs.c i386_auxv.c
|
||||
cpu_i386 = ../libcpu/libcpu_i386.a
|
||||
libebl_i386_pic_a_SOURCES = $(i386_SRCS)
|
||||
am_libebl_i386_pic_a_OBJECTS = $(i386_SRCS:.c=.os)
|
||||
|
||||
@@ -80,6 +72,7 @@ am_libebl_sh_pic_a_OBJECTS = $(sh_SRCS:.c=.os)
|
||||
|
||||
x86_64_SRCS = x86_64_init.c x86_64_symbol.c x86_64_corenote.c \
|
||||
x86_64_retval.c x86_64_regs.c i386_auxv.c
|
||||
cpu_x86_64 = ../libcpu/libcpu_x86_64.a
|
||||
libebl_x86_64_pic_a_SOURCES = $(x86_64_SRCS)
|
||||
am_libebl_x86_64_pic_a_OBJECTS = $(x86_64_SRCS:.c=.os)
|
||||
|
||||
@@ -116,6 +109,21 @@ libebl_s390_pic_a_SOURCES = $(s390_SRCS)
|
||||
am_libebl_s390_pic_a_OBJECTS = $(s390_SRCS:.c=.os)
|
||||
|
||||
|
||||
libebl_%.so: libebl_%_pic.a libebl_%.map $(libelf) $(libdw) \
|
||||
$(cpu_$(@:libebl_%.so=%)
|
||||
$(LINK) -shared -o $@ -Wl,--whole-archive,$<\
|
||||
$(cpu_$(@:libebl_%.so=%)) -Wl,--no-whole-archive \
|
||||
-Wl,--version-script,$(word 2,$^) \
|
||||
-Wl,-z,defs -Wl,--as-needed $(libelf) $(libdw) $(libmudflap)
|
||||
$(textrel_check)
|
||||
|
||||
# XXX Should not be needed...
|
||||
libebl_i386.so: $(cpu_i386)
|
||||
libebl_x86_64.so: $(cpu_x86_64)
|
||||
|
||||
libebl_%.map: Makefile
|
||||
echo 'ELFUTILS_$(PACKAGE_VERSION) { global: $*_init; local: *; };' > $@
|
||||
|
||||
%.os: %.c
|
||||
if $(COMPILE) -c -o $@ -fpic -DPIC -DSHARED -MT $@ -MD -MP \
|
||||
-MF "$(DEPDIR)/$*.Tpo" `test -f '$<' || echo '$(srcdir)/'`$<; \
|
||||
|
||||
@@ -57,6 +57,7 @@ i386_init (elf, machine, eh, ehlen)
|
||||
HOOK (eh, return_value_location);
|
||||
HOOK (eh, register_info);
|
||||
HOOK (eh, auxv_info);
|
||||
HOOK (eh, disasm);
|
||||
|
||||
return MODVERSION;
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@ x86_64_init (elf, machine, eh, ehlen)
|
||||
HOOK (eh, return_value_location);
|
||||
HOOK (eh, register_info);
|
||||
HOOK (eh, auxv_info);
|
||||
HOOK (eh, disasm);
|
||||
|
||||
return MODVERSION;
|
||||
}
|
||||
|
||||
+50
-3
@@ -134,7 +134,15 @@ if test "$use_mudflap" = fail; then
|
||||
fi
|
||||
AM_CONDITIONAL(MUDFLAP, test "$use_mudflap" = yes)
|
||||
|
||||
# Enable gprof suport.
|
||||
dnl enable debugging of branch prediction.
|
||||
use_debugpred=0
|
||||
AC_ARG_ENABLE([debugpred],
|
||||
AC_HELP_STRING([--enable-debugpred],
|
||||
[build binaries with support to debug branch prediction]),
|
||||
[use_debugpred=1], [use_debugpred=0])
|
||||
AC_SUBST([DEBUGPRED], $use_debugpred)
|
||||
|
||||
dnl Enable gprof suport.
|
||||
AC_ARG_ENABLE([gprof],
|
||||
AC_HELP_STRING([--enable-gprof],
|
||||
[build binaries with gprof support]), [use_gprof=yes], [use_gprof=no])
|
||||
@@ -267,8 +275,47 @@ AH_BOTTOM([
|
||||
# define ALLOW_UNALIGNED 0
|
||||
#endif
|
||||
|
||||
#define unlikely(expr) __builtin_expect (expr, 0)
|
||||
#define likely(expr) __builtin_expect (expr, 1)
|
||||
#if DEBUGPRED
|
||||
# ifdef __x86_64__
|
||||
asm (".section predict_data, \"aw\"; .previous\n"
|
||||
".section predict_line, \"a\"; .previous\n"
|
||||
".section predict_file, \"a\"; .previous");
|
||||
# ifndef PIC
|
||||
# define debugpred__(e, E) \
|
||||
({ long int _e = !!(e); \
|
||||
asm volatile (".pushsection predict_data; ..predictcnt%=: .quad 0; .quad 0\n" \
|
||||
".section predict_line; .quad %c1\n" \
|
||||
".section predict_file; .quad %c2; .popsection\n" \
|
||||
"addq $1,..predictcnt%=(,%0,8)" \
|
||||
: : "r" (_e == E), "i" (__LINE__), "i" (__FILE__)); \
|
||||
__builtin_expect (_e, E); \
|
||||
})
|
||||
# endif
|
||||
# elif defined __i386__
|
||||
asm (".section predict_data, \"aw\"; .previous\n"
|
||||
".section predict_line, \"a\"; .previous\n"
|
||||
".section predict_file, \"a\"; .previous");
|
||||
# ifndef PIC
|
||||
# define debugpred__(e, E) \
|
||||
({ long int _e = !!(e); \
|
||||
asm volatile (".pushsection predict_data; ..predictcnt%=: .long 0; .long 0\n" \
|
||||
".section predict_line; .long %c1\n" \
|
||||
".section predict_file; .long %c2; .popsection\n" \
|
||||
"incl ..predictcnt%=(,%0,8)" \
|
||||
: : "r" (_e == E), "i" (__LINE__), "i" (__FILE__)); \
|
||||
__builtin_expect (_e, E); \
|
||||
})
|
||||
# endif
|
||||
# endif
|
||||
# ifdef debugpred__
|
||||
# define unlikely(e) debugpred__ (e,0)
|
||||
# define likely(e) debugpred__ (e,1)
|
||||
# endif
|
||||
#endif
|
||||
#ifndef likely
|
||||
# define unlikely(expr) __builtin_expect (!!(expr), 0)
|
||||
# define likely(expr) __builtin_expect (!!(expr), 1)
|
||||
#endif
|
||||
|
||||
#define obstack_calloc(ob, size) \
|
||||
({ size_t _s = (size); memset (obstack_alloc (ob, _s), '\0', _s); })
|
||||
|
||||
@@ -1,3 +1,14 @@
|
||||
2007-12-20 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* disasm_cb.c: Add initial support to resolve addresses to symbols.
|
||||
|
||||
2007-02-05 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* disasm_begin.c: New file.
|
||||
* disasm_cb.c: New file.
|
||||
* disasm_end.c: New file.
|
||||
* disasm_str.c: New file.
|
||||
|
||||
2006-08-29 Roland McGrath <roland@redhat.com>
|
||||
|
||||
* Makefile.am (CLEANFILES): Add libasm.so.$(VERSION).
|
||||
|
||||
@@ -59,6 +59,7 @@ libasm_a_SOURCES = asm_begin.c asm_abort.c asm_end.c asm_error.c \
|
||||
asm_addint32.c asm_adduint32.c \
|
||||
asm_addint64.c asm_adduint64.c \
|
||||
asm_adduleb128.c asm_addsleb128.c \
|
||||
disasm_begin.c disasm_cb.c disasm_end.c disasm_str.c \
|
||||
symbolhash.c
|
||||
|
||||
if !MUDFLAP
|
||||
|
||||
@@ -126,6 +126,7 @@ static const char *msgs[ASM_E_NUM] =
|
||||
[ASM_E_DUPLSYM] = N_("duplicate symbol"),
|
||||
[ASM_E_TYPE] = N_("invalid section type for operation"),
|
||||
[ASM_E_IOERROR] = N_("error during output of data"),
|
||||
[ASM_E_ENOSUP] = N_("no backend support available"),
|
||||
};
|
||||
|
||||
const char *
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/* Create context descriptor for disassembler.
|
||||
Copyright (C) 2005 Red Hat, Inc.
|
||||
Written by Ulrich Drepper <drepper@redhat.com>, 2005.
|
||||
|
||||
This program is Open Source software; you can redistribute it and/or
|
||||
modify it under the terms of the Open Software License version 1.0 as
|
||||
published by the Open Source Initiative.
|
||||
|
||||
You should have received a copy of the Open Software License along
|
||||
with this program; if not, you may obtain a copy of the Open Software
|
||||
License version 1.0 from http://www.opensource.org/licenses/osl.php or
|
||||
by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
|
||||
3001 King Ranch Road, Ukiah, CA 95482. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "libasmP.h"
|
||||
#include "../libebl/libeblP.h"
|
||||
|
||||
|
||||
DisasmCtx_t *
|
||||
disasm_begin (Ebl *ebl, Elf *elf, DisasmGetSymCB_t symcb)
|
||||
{
|
||||
if (ebl == NULL)
|
||||
return NULL;
|
||||
|
||||
if (ebl->disasm == NULL)
|
||||
{
|
||||
__libasm_seterrno (ASM_E_ENOSUP);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DisasmCtx_t *ctx = (DisasmCtx_t *) malloc (sizeof (DisasmCtx_t));
|
||||
if (ctx == NULL)
|
||||
{
|
||||
__libasm_seterrno (ASM_E_NOMEM);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctx->ebl = ebl;
|
||||
ctx->elf = elf;
|
||||
ctx->symcb = symcb;
|
||||
|
||||
return ctx;
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
/* Copyright (C) 2005, 2007 Red Hat, Inc.
|
||||
This file is part of Red Hat elfutils.
|
||||
Written by Ulrich Drepper <drepper@redhat.com>, 2005.
|
||||
|
||||
Red Hat elfutils is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; version 2 of the License.
|
||||
|
||||
Red Hat elfutils is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with Red Hat elfutils; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
|
||||
|
||||
Red Hat elfutils is an included package of the Open Invention Network.
|
||||
An included package of the Open Invention Network is a package for which
|
||||
Open Invention Network licensees cross-license their patents. No patent
|
||||
license is granted, either expressly or impliedly, by designation as an
|
||||
included package. Should you wish to participate in the Open Invention
|
||||
Network licensing program, please visit www.openinventionnetwork.com
|
||||
<http://www.openinventionnetwork.com>. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "libasmP.h"
|
||||
#include "../libebl/libeblP.h"
|
||||
|
||||
|
||||
struct symtoken
|
||||
{
|
||||
DisasmCtx_t *ctx;
|
||||
void *symcbarg;
|
||||
};
|
||||
|
||||
|
||||
static int
|
||||
default_elf_getsym (GElf_Addr addr, Elf32_Word scnndx, GElf_Addr value,
|
||||
char *buf, size_t buflen, void *arg)
|
||||
{
|
||||
struct symtoken *symtoken = (struct symtoken *) arg;
|
||||
|
||||
/* First try the user provided function. */
|
||||
if (symtoken->ctx->symcb != NULL)
|
||||
{
|
||||
int res = symtoken->ctx->symcb (addr, scnndx, value, buf, buflen,
|
||||
symtoken->symcbarg);
|
||||
if (res >= 0)
|
||||
return res;
|
||||
}
|
||||
|
||||
// XXX Look up in ELF file.
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
struct symaddrpair
|
||||
{
|
||||
GElf_Addr addr;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
read_symtab_exec (DisasmCtx_t *ctx)
|
||||
{
|
||||
/* We simply use all we can get our hands on. This will produce
|
||||
some duplicate information but this is no problem, we simply
|
||||
ignore the latter definitions. */
|
||||
Elf_Scn *scn= NULL;
|
||||
while ((scn = elf_nextscn (ctx->elf, scn)) != NULL)
|
||||
{
|
||||
GElf_Shdr shdr_mem;
|
||||
GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
|
||||
Elf_Data *data;
|
||||
if (shdr == NULL || shdr->sh_type != SHT_SYMTAB
|
||||
|| (data = elf_getdata (scn, NULL)) == NULL)
|
||||
continue;
|
||||
|
||||
int xndxscnidx = elf_scnshndx (scn);
|
||||
Elf_Data *xndxdata = NULL;
|
||||
if (xndxscnidx > 0)
|
||||
xndxdata = elf_getdata (elf_getscn (ctx->elf, xndxscnidx), NULL);
|
||||
|
||||
/* Iterate over all symbols. Add all defined symbols. */
|
||||
int nsyms = shdr->sh_size / shdr->sh_entsize;
|
||||
for (int cnt = 1; cnt < nsyms; ++cnt)
|
||||
{
|
||||
Elf32_Word xshndx;
|
||||
GElf_Sym sym_mem;
|
||||
GElf_Sym *sym = gelf_getsymshndx (data, xndxdata, cnt, &sym_mem,
|
||||
&xshndx);
|
||||
if (sym == NULL)
|
||||
continue;
|
||||
|
||||
/* Undefined symbols are useless here. */
|
||||
if (sym->st_shndx == SHN_UNDEF)
|
||||
continue;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
read_symtab (DisasmCtx_t *ctx)
|
||||
{
|
||||
/* Find the symbol table(s). */
|
||||
GElf_Ehdr ehdr_mem;
|
||||
GElf_Ehdr *ehdr = gelf_getehdr (ctx->elf, &ehdr_mem);
|
||||
if (ehdr == NULL)
|
||||
return;
|
||||
|
||||
switch (ehdr->e_type)
|
||||
{
|
||||
case ET_EXEC:
|
||||
case ET_DYN:
|
||||
read_symtab_exec (ctx);
|
||||
break;
|
||||
|
||||
case ET_REL:
|
||||
// XXX Handle
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
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)),
|
||||
void *arg __attribute__ ((unused)))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
disasm_cb (DisasmCtx_t *ctx, const uint8_t **startp, const uint8_t *end,
|
||||
GElf_Addr addr, const char *fmt, DisasmOutputCB_t outcb,
|
||||
void *outcbarg, void *symcbarg)
|
||||
{
|
||||
struct symtoken symtoken;
|
||||
DisasmGetSymCB_t getsym = ctx->symcb ?: null_elf_getsym;
|
||||
|
||||
if (ctx->elf != NULL)
|
||||
{
|
||||
/* Read all symbols of the ELF file and stuff them into a hash
|
||||
table. The key is the address and the section index. */
|
||||
read_symtab (ctx);
|
||||
|
||||
symtoken.ctx = ctx;
|
||||
symtoken.symcbarg = symcbarg;
|
||||
|
||||
symcbarg = &symtoken;
|
||||
|
||||
getsym = default_elf_getsym;
|
||||
}
|
||||
|
||||
return ctx->ebl->disasm (startp, end, addr, fmt, outcb, getsym, outcbarg,
|
||||
symcbarg);
|
||||
}
|
||||
INTDEF (disasm_cb)
|
||||
@@ -0,0 +1,30 @@
|
||||
/* Release descriptor for disassembler.
|
||||
Copyright (C) 2005 Red Hat, Inc.
|
||||
Written by Ulrich Drepper <drepper@redhat.com>, 2005.
|
||||
|
||||
This program is Open Source software; you can redistribute it and/or
|
||||
modify it under the terms of the Open Software License version 1.0 as
|
||||
published by the Open Source Initiative.
|
||||
|
||||
You should have received a copy of the Open Software License along
|
||||
with this program; if not, you may obtain a copy of the Open Software
|
||||
License version 1.0 from http://www.opensource.org/licenses/osl.php or
|
||||
by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
|
||||
3001 King Ranch Road, Ukiah, CA 95482. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "libasmP.h"
|
||||
|
||||
|
||||
int
|
||||
disasm_end (DisasmCtx_t *ctx)
|
||||
{
|
||||
free (ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/* Copyright (C) 2005 Red Hat, Inc.
|
||||
|
||||
This program is Open Source software; you can redistribute it and/or
|
||||
modify it under the terms of the Open Software License version 1.0 as
|
||||
published by the Open Source Initiative.
|
||||
|
||||
You should have received a copy of the Open Software License along
|
||||
with this program; if not, you may obtain a copy of the Open Software
|
||||
License version 1.0 from http://www.opensource.org/licenses/osl.php or
|
||||
by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
|
||||
3001 King Ranch Road, Ukiah, CA 95482. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "libasmP.h"
|
||||
|
||||
|
||||
struct buffer
|
||||
{
|
||||
char *buf;
|
||||
size_t len;
|
||||
};
|
||||
|
||||
|
||||
static int
|
||||
buffer_cb (char *str, size_t len, void *arg)
|
||||
{
|
||||
struct buffer *buffer = (struct buffer *) arg;
|
||||
|
||||
if (len > buffer->len)
|
||||
/* Return additional needed space. */
|
||||
return len - buffer->len;
|
||||
|
||||
buffer->buf = mempcpy (buffer->buf, str, len);
|
||||
buffer->len = len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
disasm_str (DisasmCtx_t *ctx, const uint8_t **startp, const uint8_t *end,
|
||||
GElf_Addr addr, const char *fmt, char **bufp, size_t len,
|
||||
void *symcbarg)
|
||||
{
|
||||
struct buffer buffer = { .buf = *bufp, .len = len };
|
||||
|
||||
int res = INTUSE(disasm_cb) (ctx, startp, end, addr, fmt, buffer_cb, &buffer,
|
||||
symcbarg);
|
||||
*bufp = buffer.buf;
|
||||
return res;
|
||||
}
|
||||
@@ -45,6 +45,20 @@ typedef struct AsmScnGrp AsmScnGrp_t;
|
||||
typedef struct AsmSym AsmSym_t;
|
||||
|
||||
|
||||
/* Opaque type for the disassembler context descriptor. */
|
||||
typedef struct DisasmCtx DisasmCtx_t;
|
||||
|
||||
/* Type used for callback functions to retrieve symbol name. The
|
||||
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 *);
|
||||
|
||||
/* Output function callback. */
|
||||
typedef int (*DisasmOutputCB_t) (char *, size_t, void *);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -159,6 +173,25 @@ extern int asm_errno (void);
|
||||
string is returned. */
|
||||
extern const char *asm_errmsg (int __error);
|
||||
|
||||
|
||||
/* Create context descriptor for disassembler. */
|
||||
extern DisasmCtx_t *disasm_begin (Ebl *ebl, Elf *elf, DisasmGetSymCB_t symcb);
|
||||
|
||||
/* Release descriptor for disassembler. */
|
||||
extern int disasm_end (DisasmCtx_t *ctx);
|
||||
|
||||
/* Produce of disassembly output for given memory, store text in
|
||||
provided buffer. */
|
||||
extern int disasm_str (DisasmCtx_t *ctx, const uint8_t **startp,
|
||||
const uint8_t *end, GElf_Addr addr, const char *fmt,
|
||||
char **bufp, size_t len, void *symcbarg);
|
||||
|
||||
/* Produce disassembly output for given memory and output it using the
|
||||
given callback functions. */
|
||||
extern int disasm_cb (DisasmCtx_t *ctx, const uint8_t **startp,
|
||||
const uint8_t *end, GElf_Addr addr, const char *fmt,
|
||||
DisasmOutputCB_t outcb, void *outcbarg, void *symcbarg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -28,6 +28,11 @@ ELFUTILS_1.0 {
|
||||
asm_newsym;
|
||||
asm_scngrp_newsignature;
|
||||
|
||||
disasm_begin;
|
||||
disasm_cb;
|
||||
disasm_end;
|
||||
disasm_str;
|
||||
|
||||
local:
|
||||
*;
|
||||
};
|
||||
|
||||
@@ -47,6 +47,7 @@ enum
|
||||
ASM_E_LIBELF, /* Refer to error in libelf. */
|
||||
ASM_E_TYPE, /* Invalid section type for operation. */
|
||||
ASM_E_IOERROR, /* Error during output of data. */
|
||||
ASM_E_ENOSUP, /* No backend support. */
|
||||
ASM_E_NUM /* Keep this entry as the last. */
|
||||
};
|
||||
|
||||
@@ -235,6 +236,21 @@ struct AsmScnGrp
|
||||
};
|
||||
|
||||
|
||||
/* Descriptor for disassembler. */
|
||||
struct DisasmCtx
|
||||
{
|
||||
/* Handle for the backend library with the disassembler routine. */
|
||||
Ebl *ebl;
|
||||
|
||||
/* ELF file containing all the data passed to the function. This
|
||||
allows to look up symbols. */
|
||||
Elf *elf;
|
||||
|
||||
/* Callback function to determine symbol names. */
|
||||
DisasmGetSymCB_t symcb;
|
||||
};
|
||||
|
||||
|
||||
/* The default fill pattern: one zero byte. */
|
||||
extern const struct FillPattern *__libasm_default_pattern
|
||||
attribute_hidden;
|
||||
@@ -269,6 +285,14 @@ extern int __asm_addint64_internal (AsmScn_t *asmscn, int64_t num)
|
||||
attribute_hidden;
|
||||
|
||||
|
||||
/* Produce disassembly output for given memory and output it using the
|
||||
given callback functions. */
|
||||
extern int __disasm_cb_internal (DisasmCtx_t *ctx, const uint8_t **startp,
|
||||
const uint8_t *end, GElf_Addr addr,
|
||||
const char *fmt, DisasmOutputCB_t outcb,
|
||||
void *outcbarp, void *symcbarg)
|
||||
attribute_hidden;
|
||||
|
||||
|
||||
/* Test whether given symbol is an internal symbol and if yes, whether
|
||||
we should nevertheless emit it in the symbol table. */
|
||||
|
||||
@@ -1,3 +1,184 @@
|
||||
2008-01-01 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* defs/i386: More 0f prefix support.
|
||||
* i386_data.h (FCT_mmxreg): Implement.
|
||||
(FCT_mmxreg2): Implement.
|
||||
(FCT_mmreg): Remove.
|
||||
* i386_disasm.c (i386_disasm): More special instructions.
|
||||
Fix tttn suffix for cmov.
|
||||
* i386_parse.y: Simplify test for mod/r_m mode.
|
||||
|
||||
2007-12-31 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* defs/i386: Fix order or arguments for mov of control/debug registers.
|
||||
* i386_data.h (FCT_ccc): Implement
|
||||
(FCT_ddd): Implement
|
||||
|
||||
2007-12-30 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* defs/i386: Fix 0f groups 6 and 7.
|
||||
* i386_data.c (FCT_mod$16r_m): Implement.
|
||||
* i386_disasm.c (i386_disasm): Third parameter can also have string.
|
||||
|
||||
2007-12-29 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* defs/i386: Add lots of floating point ops.
|
||||
* i386_data.h (FCT_fmod$fr_m): Removed.
|
||||
(FCT_freg): Implement.
|
||||
* i386_disasm.c (i386_disasm): Implement suffix_D.
|
||||
* i386_parse.y: Emit suffix_D.
|
||||
|
||||
* defs/i386: Use rel instead of dispA.
|
||||
Fix lcall, dec, div, idiv, imul, inc, jmp, ljmp, mul, neg, not, push,
|
||||
test.
|
||||
|
||||
* i386_data.h (FCT_dispA): Removed.
|
||||
(FCT_ds_xx): Add test for end of input buffer.
|
||||
* i386_disasm.c (ABORT_ENTRY): Removed.
|
||||
(i386_disasm): Fix handling of SIB. Pass correct address value to
|
||||
operand callbacks.
|
||||
|
||||
* Makefile.am (*.mnemonics): Filter out INVALID entry.
|
||||
* defs/i386: Define imms8 and use in appropriate places.
|
||||
Add INVALID entries for special opcodes with special mnemonics.
|
||||
Fix int3. Fix typo in shl. Correct xlat.
|
||||
* i386_data.h (FCT_ds_xx): New function.
|
||||
(FCT_ds_si): Use it.
|
||||
(FCT_ds_bx): New function.
|
||||
(FCT_imms8): New function.
|
||||
* i386_disasm.c (MNE_INVALID): Define.
|
||||
(i386_disasm): Handle invalid opcodes in mnemonics printing, not
|
||||
separately. Fix address value passed to operand handlers.
|
||||
* i386_parse.y (bx_reg): Define.
|
||||
(instrtable_out): Handle INVALID entries differently, just use
|
||||
MNE_INVALID value for .mnemonic.
|
||||
|
||||
2007-12-28 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* defs/i386: Fix shift and mov immediate instructions.
|
||||
* i386_data.h (FCT_imm16): Implement.
|
||||
|
||||
* defs/i386: Use absval instead of abs of lcall and ljmp.
|
||||
Add parameters for cmps. Fix test and mov immediate.
|
||||
* i386_data.h: Implement FCT_absval.
|
||||
* i386_disasm.c: Handle data16 for suffix_w and FCT_imm.
|
||||
|
||||
* defs/i386: Move entries with 0x9b prefix together.
|
||||
* i386_disasm.c (i386_disasm): Fix recognizing insufficient bytes in
|
||||
input. Handle data16 with suffix_W.
|
||||
|
||||
* i386_data.h (FCT_*): Add end parameter to all functions. Check
|
||||
before using more bytes.
|
||||
(FCT_sel): Implement.
|
||||
* i386_disasm.c (i386_disasm): Better handle end of input buffer.
|
||||
Specal opcode 0x99.
|
||||
|
||||
* Makefile.am: Use m4 to preprocess defs/* files.
|
||||
* defs/i386: Adjust appropriately.
|
||||
* i386_data.c (FCT_ax): Implement.
|
||||
(FCT_ax$w): Use FCT_ax.
|
||||
* i386_disasm.c (ADD_STRING): Use _len instead of len.
|
||||
(i386_disasm): If no instruction can be matched because of lack of
|
||||
input and prefixes have been matched, print prefixes.
|
||||
Recognize abort entries.
|
||||
Handle special cases.
|
||||
* i386_gendis.c: Recognize - input file name.
|
||||
* i386_lex.c: Recognize INVALID token.
|
||||
* i386_parse.y: Handle INVALID token input.
|
||||
|
||||
* defs/i386: Fix mov, pop.
|
||||
* i386_data.h (FCT_sreg3): Implement.
|
||||
|
||||
2007-12-27 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* defs/i386: Fix adc, add, cmp, or, sbb, sub, xchg, xor.
|
||||
* i386_data.h (FCT_imms): New function.
|
||||
(FCT_imm$s): Use FCT_imms for handling of signed values.
|
||||
(FCT_imm8): Sign extend values.
|
||||
* i386_disasm.c (i386_disasm): Implement suffix_w0.
|
||||
* i386_parse.y: Emit suffix w0.
|
||||
|
||||
* i386_data.h (FCT_disp8): Add 0x prefix.
|
||||
(FCT_ds_si): Implement.
|
||||
* i386_disasm.c (i386_disasm): Increment addr for invalid prefixes.
|
||||
Implement tttn suffix.
|
||||
* i386_parse.y: Emit tttn suffix definition.
|
||||
|
||||
2007-12-26 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* i386_data.h (struct instr_enc): Use suffix field.
|
||||
(FCT_dx): Fill in body.
|
||||
(FCT_es_di): Likewise.
|
||||
(FCT_imm$s): Sign-extended byte values.
|
||||
* i386_disasm.c: Protect ADD_CHAR and ADD_STRING macros. Adjust uses.
|
||||
(i386_disasm): Handle suffix.
|
||||
* i386_parse.y: Emit suffix information.
|
||||
* defs/i386: Remove unnecessary suffixes.
|
||||
|
||||
* Makefile.am: Disable building x86-64 version for now.
|
||||
|
||||
* defs/i386: Fix and, bound, cmp, or, pop, sbb, sub, xor.
|
||||
* i386_data.h: Pass pointer to prefix to functions. If not prefixes
|
||||
are consumed this means invalid input.
|
||||
* i386_disasm.c: Fix prefix printing. Adjust function calls for
|
||||
parameter change.
|
||||
* i386_parse.y: Recognize moda prefix.
|
||||
|
||||
2007-12-21 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* i386_data.h: Fix SIB handling.
|
||||
* i386_disasm.c: Likewise.
|
||||
|
||||
2007-12-19 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* defs/i386: Fix up 'and' opcode.
|
||||
|
||||
2007-10-31 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* Makefile.am: Add dependencies of the generated files on the source
|
||||
files.
|
||||
(i386_lex_CFLAGS): Add -Wno-sign-compare.
|
||||
|
||||
* defs/i386: A lot more data.
|
||||
* defs/x86_64: Likewise.
|
||||
* i386_data.h (struct instr_enc): Add off1_3, off2_3, and off3_3
|
||||
fields.
|
||||
(opfct_t): Add parameter for third operand.
|
||||
(FCT_*): Likewise.
|
||||
(data_prefix): New function.
|
||||
(FCT_abs): Implement.
|
||||
(FCT_ax): Renamed to FCT_ax$w amd implement.
|
||||
(FCT_disp8): Implement.
|
||||
(FCT_dispA): Implement.
|
||||
(FCT_imm): Implement.
|
||||
(FCT_imm$w): Implement.
|
||||
(FCT_imm$s): Don't zero-pad numbers.
|
||||
(FCT_imm8): Likewise.
|
||||
(FCT_rel): Likewise.
|
||||
(general_mod$r_m): New function.
|
||||
(FCT_mod$r_m): Use it.
|
||||
(FCT_mod$r_m$w): New function.
|
||||
(FCT_mod$8r_m): New function.
|
||||
(FCT_reg): Correctly handle 16-bit registers.
|
||||
(FCT_reg$w): New function.
|
||||
* i386_disasm.c (i386_disasm): Handle prefixes better.
|
||||
Pass third parameter to operand functions.
|
||||
* i386_parse.y (struct instruction): Add off3 field.
|
||||
Handle third operand throughout.
|
||||
|
||||
2007-02-05 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* i386_disasm.c: New file.
|
||||
* i386_data.h: New file.
|
||||
* i386_gendis.c: New file.
|
||||
* i386_lex.l: New file.
|
||||
* i386_parse.y: New file.
|
||||
* memory-access.h: New file.
|
||||
* x86_64_disasm.c: New file.
|
||||
* defs/i386: New file.
|
||||
* defs/i386.doc: New file.
|
||||
* defs/x86_64: New file.
|
||||
|
||||
2005-02-15 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* Makefile (AM_CFLAGS): Add -Wunused -Wextra -Wformat=2.
|
||||
|
||||
+52
-5
@@ -1,6 +1,6 @@
|
||||
## Process this file with automake to create Makefile.in
|
||||
##
|
||||
## Copyright (C) 2002, 2005 Red Hat, Inc.
|
||||
## Copyright (C) 2002, 2004, 2005, 2007 Red Hat, Inc.
|
||||
## This file is part of Red Hat elfutils.
|
||||
##
|
||||
## Red Hat elfutils is free software; you can redistribute it and/or modify
|
||||
@@ -25,9 +25,56 @@
|
||||
## <http://www.openinventionnetwork.com>.
|
||||
##
|
||||
DEFS = -D_GNU_SOURCE -DHAVE_CONFIG_H
|
||||
AM_CFLAGS = -Wall -Wshadow -Werror -Wextra -Wformat=2 -Wunused
|
||||
INCLUDES = -I$(srcdir)
|
||||
if MUDFLAP
|
||||
AM_CFLAGS = -fmudflap
|
||||
else
|
||||
AM_CFLAGS =
|
||||
endif
|
||||
AM_CFLAGS += -Wall -Wshadow -Werror -Wunused -Wextra -std=gnu99 -fpic \
|
||||
$($(*F)_CFLAGS)
|
||||
INCLUDES = -I$(srcdir) -I$(srcdir)/../lib -I$(srcdir)/../libelf \
|
||||
-I$(srcdir)/../libebl -I$(srcdir)/../libdw -I$(srcdir)/../libasm
|
||||
LEXCOMPILE = $(LEX) $(LFLAGS) $(AM_LFLAGS) -P$(<F:lex.l=)
|
||||
LEX_OUTPUT_ROOT = lex.$(<F:lex.l=)
|
||||
AM_YFLAGS = -p$(<F:parse.y=)
|
||||
|
||||
noinst_LIBRARIES = libcpu_i386.a
|
||||
if MUDFLAP
|
||||
libmudflap = -lmudflap
|
||||
endif
|
||||
|
||||
libcpu_i386_a_SOURCES = i386_dis.c
|
||||
# XXX x86-64 uncommented for now.
|
||||
noinst_LIBRARIES = libcpu_i386.a# libcpu_x86_64.a
|
||||
noinst_PROGRAMS = i386_gendis
|
||||
|
||||
libcpu_i386_a_SOURCES = i386_disasm.c
|
||||
# XXX Unused for now.
|
||||
#libcpu_x86_64_a_SOURCES = x86_64_disasm.c
|
||||
|
||||
i386_gendis_SOURCES = i386_gendis.c i386_lex.l i386_parse.y
|
||||
|
||||
i386_disasm.o: i386.mnemonics i386_dis.h
|
||||
x86_64_disasm.o: x86_64.mnemonics x86_64_dis.h i386_disasm.c
|
||||
|
||||
i386_dis.h: i386_gendis $(srcdir)/defs/i386
|
||||
m4 -Di386 -DDISASSEMBLER $(srcdir)/defs/i386 | ./i386_gendis - > $@
|
||||
x86_64_dis.h: i386_gendis $(srcdir)/defs/x86_64
|
||||
m4 -Dx86_64 -DDISASSEMBLER $(srcdir)/defs/x86_64 | ./i386_gendis - > $@
|
||||
|
||||
i386.mnemonics x86_64.mnemonics: %.mnemonics: $(srcdir)/defs/%
|
||||
m4 -D$(<F) -DDISASSEMBLER $^ \
|
||||
| sed '1,/^%%/d;/^#/d;/^[[:space:]]*$$/d;s/[^:]*:\([^[:space:]]*\).*/MNE(\1)/;s/{[^}]*}//g;/INVALID/d' \
|
||||
| sort -u > $@
|
||||
|
||||
libeu = ../lib/libeu.a
|
||||
|
||||
i386_lex_CFLAGS = -Wno-unused-label -Wno-unused-function -Wno-sign-compare
|
||||
i386_gendis.o: i386_parse.c i386.mnemonics
|
||||
i386_parse_CFLAGS = -DNMNES=$$(wc -l < i386.mnemonics)
|
||||
i386_lex.o: i386_parse.c
|
||||
i386_gendis_LDADD = $(libeu) -lm $(libmudflap)
|
||||
|
||||
noinst_HEADERS = memory-access.h i386_parse.h i386_data.h
|
||||
|
||||
EXTRA_DIST = defs/i386 defs/x86_64
|
||||
|
||||
CLEANFILES = i386.mnemonics i386_dis.h x86_64.mnemonics x86_64_dis.h
|
||||
|
||||
@@ -0,0 +1,634 @@
|
||||
%mask {s} 1
|
||||
%mask {w} 1
|
||||
%mask {w1} 1
|
||||
dnl floating point reg suffix
|
||||
%mask {D} 1
|
||||
%mask {imm8} 8
|
||||
%mask {imms8} 8
|
||||
%mask {imm16} 16
|
||||
%mask {reg} 3
|
||||
%mask {reg16} 3
|
||||
%mask {tttn} 4
|
||||
%mask {gg} 2
|
||||
%mask {mod} 2
|
||||
%mask {moda} 2
|
||||
%mask {MOD} 2
|
||||
%mask {r_m} 3
|
||||
dnl like {r_m} but referencing byte register
|
||||
%mask {8r_m} 3
|
||||
dnl like {r_m} but referencing 16-bit register
|
||||
%mask {16r_m} 3
|
||||
%mask {disp8} 8
|
||||
dnl imm really is 8/16/32 bit depending on the situation.
|
||||
%mask {imm} 8
|
||||
%mask {imms} 8
|
||||
%mask {rel} 32
|
||||
%mask {abs} 32
|
||||
%mask {absval} 32
|
||||
%mask {sel} 16
|
||||
%mask {imm32} 32
|
||||
%mask {ccc} 3
|
||||
%mask {ddd} 3
|
||||
%mask {sreg3} 3
|
||||
%mask {sreg2} 2
|
||||
%mask {mmxreg} 3
|
||||
%mask {mmxreg2} 3
|
||||
%mask {R_M} 3
|
||||
%mask {0g} 2
|
||||
%mask {GG} 2
|
||||
%mask {gG} 2
|
||||
%mask {Mod} 2
|
||||
%mask {xmmreg} 3
|
||||
%mask {R_m} 3
|
||||
%mask {mmreg} 3
|
||||
%mask {xmmreg1} 3
|
||||
%mask {xmmreg2} 3
|
||||
%mask {predpd} 8
|
||||
%mask {predps} 8
|
||||
%mask {predsd} 8
|
||||
%mask {predss} 8
|
||||
%mask {freg} 3
|
||||
%mask {fmod} 2
|
||||
%mask {fr_m} 3
|
||||
%prefix {R}
|
||||
%prefix {RE}
|
||||
%suffix {W}
|
||||
%suffix {w0}
|
||||
%synonym {xmmreg1} {xmmreg}
|
||||
%synonym {xmmreg2} {xmmreg}
|
||||
|
||||
%%
|
||||
ifdef(`i386',
|
||||
`00110111:aaa
|
||||
11010101,00001010:aad
|
||||
11010100,00001010:aam
|
||||
00111111:aas
|
||||
')dnl
|
||||
0001010{w},{imm}:adc {imm}{w},{ax}{w}
|
||||
1000000{w},{mod}010{r_m},{imm}:adc{w} {imm}{w},{mod}{r_m}{w}
|
||||
1000001{w},{mod}010{r_m},{imms8}:adc{w} {imms8},{mod}{r_m}
|
||||
0001000{w},{mod}{reg}{r_m}:adc {reg}{w},{mod}{r_m}
|
||||
0001001{w},{mod}{reg}{r_m}:adc {mod}{r_m},{reg}{w}
|
||||
0000010{w},{imm}:add {imm}{w},{ax}{w}
|
||||
1000000{w},{mod}000{r_m},{imm}:add{w} {imm}{w},{mod}{r_m}{w}
|
||||
10000011,{mod}000{r_m},{imms8}:add{w0} {imms8},{mod}{r_m}
|
||||
0000000{w},{mod}{reg}{r_m}:add {reg}{w},{mod}{r_m}
|
||||
0000001{w},{mod}{reg}{r_m}:add {mod}{r_m},{reg}{w}
|
||||
11110010,00001111,01011000,{Mod}{xmmreg}{R_m}:addsd {Mod}{R_m},{xmmreg}
|
||||
11110011,00001111,01011000,{Mod}{xmmreg}{R_m}:addss {Mod}{R_m},{xmmreg}
|
||||
01100110,00001111,11010000,{Mod}{xmmreg}{R_m}:addsubpd {Mod}{R_m},{xmmreg}
|
||||
11110010,00001111,11010000,{Mod}{xmmreg}{R_m}:addsubps {Mod}{R_m},{xmmreg}
|
||||
0010010{w},{imm}:and {imm}{w},{ax}{w}
|
||||
1000000{w},{mod}100{r_m},{imm}:and{w} {imm}{w},{mod}{r_m}{w}
|
||||
1000001{w},{mod}100{r_m},{imms}:and{w} {imms},{mod}{r_m}
|
||||
0010000{w},{mod}{reg}{r_m}:and {reg}{w},{mod}{r_m}{w}
|
||||
0010001{w},{mod}{reg}{r_m}:and {mod}{r_m}{w},{reg}{w}
|
||||
01100110,00001111,01010100,{Mod}{xmmreg}{R_m}:andpd {Mod}{R_m},{xmmreg}
|
||||
00001111,01010100,{Mod}{xmmreg}{R_m}:andps {Mod}{R_m},{xmmreg}
|
||||
01100110,00001111,01010101,{Mod}{xmmreg}{R_m}:andnpd {Mod}{R_m},{xmmreg}
|
||||
00001111,01010101,{Mod}{xmmreg}{R_m}:andnps {Mod}{R_m},{xmmreg}
|
||||
ifdef(`i386',
|
||||
`01100011,{mod}{reg16}{r_m}:arpl {reg16},{mod}{r_m}
|
||||
01100010,{moda}{reg}{r_m}:bound {reg},{moda}{r_m}
|
||||
')dnl
|
||||
00001111,10111100,{mod}{reg}{r_m}:bsf {reg},{mod}{r_m}
|
||||
00001111,10111101,{mod}{reg}{r_m}:bsr {reg},{mod}{r_m}
|
||||
00001111,11001{reg}:bswap {reg}
|
||||
00001111,10100011,{mod}{reg}{r_m}:bt {reg},{mod}{r_m}
|
||||
00001111,10111010,{mod}100{r_m},{imm8}:bt {imm8},{mod}{r_m}
|
||||
00001111,10111011,{mod}{reg}{r_m}:btc {reg},{mod}{r_m}
|
||||
00001111,10111010,{mod}111{r_m},{imm8}:btc {imm8},{mod}{r_m}
|
||||
00001111,10110011,{mod}{reg}{r_m}:btr {reg},{mod}{r_m}
|
||||
00001111,10111010,{mod}110{r_m},{imm8}:btr {imm8},{mod}{r_m}
|
||||
00001111,10101011,{mod}{reg}{r_m}:bts {reg},{mod}{r_m}
|
||||
00001111,10111010,{mod}101{r_m},{imm8}:bts {imm8},{mod}{r_m}
|
||||
11101000,{rel}:call {rel}
|
||||
11111111,{mod}010{r_m}:call *{mod}{r_m}
|
||||
ifdef(`i386',
|
||||
`10011010,{absval},{sel}:lcall {sel},{absval}
|
||||
')dnl
|
||||
11111111,{mod}011{r_m}:lcall *{mod}{r_m}
|
||||
# SPECIAL 10011000:[{rex.w}?cltq:{dpfx}?cbtw:cwtl]
|
||||
10011000:INVALID
|
||||
# SPECIAL 10011001:[{rew.w}?cqto:{dpfx}?cltd:cwtd]
|
||||
10011001:INVALID
|
||||
11111000:clc
|
||||
11111100:cld
|
||||
00001111,10101110,{mod}111{r_m}:clflush {mod}{r_m}
|
||||
11111010:cli
|
||||
00001111,00000101:syscall
|
||||
00001111,00000110:clts
|
||||
00001111,00000111:sysret
|
||||
00001111,00110100:sysenter
|
||||
00001111,00110101:sysexit
|
||||
11110101:cmc
|
||||
00001111,0100{tttn},{mod}{reg}{r_m}:cmov{tttn} {mod}{r_m},{reg}
|
||||
0011110{w},{imm}:cmp {imm}{w},{ax}{w}
|
||||
1000000{w},{mod}111{r_m},{imm}:cmp{w} {imm}{w},{mod}{r_m}{w}
|
||||
10000011,{mod}111{r_m},{imms8}:cmp{w0} {imms8},{mod}{r_m}
|
||||
0011100{w},{mod}{reg}{r_m}:cmp {reg}{w},{mod}{r_m}{w}
|
||||
0011101{w},{mod}{reg}{r_m}:cmp {mod}{r_m}{w},{reg}{w}
|
||||
01100110,00001111,11000010,{Mod}{xmmreg}{R_m},{predpd}:cmpl{predpd} {Mod}{R_m},{xmmreg}
|
||||
ifdef(`ASSEMBLER',
|
||||
`01100110,00001111,11000010,{Mod}{xmmreg}{R_m},{imm8}:cmppd {imm8},{Mod}{R_m},{xmmreg
|
||||
}')dnl
|
||||
00001111,11000010,{Mod}{xmmreg}{R_m},{predps}:cmpl{predps} {Mod}{R_m},{xmmreg}
|
||||
ifdef(`ASSEMBLER',
|
||||
`00001111,11000010,{Mod}{xmmreg}{R_m},{imm8}:cmpps {imm8},{Mod}{R_m},{xmmreg}
|
||||
')dnl
|
||||
1010011{w}:{RE}cmps{w} {es_di},{ds_si}
|
||||
11110010,00001111,11000010,{Mod}{xmmreg}{R_m},{predsd}:cmpl{predsd} {Mod}{R_m},{xmmreg}
|
||||
ifdef(`ASSEMBLER',
|
||||
`11110010,00001111,11000010,{Mod}{xmmreg}{R_m},{imm8}:cmpsd {imm8},{Mod}{R_m},{xmmreg}
|
||||
')dnl
|
||||
11110011,00001111,11000010,{Mod}{xmmreg}{R_m},{predss}:cmpl{predss} {Mod}{R_m},{xmmreg}
|
||||
ifdef(`ASSEMBLER',
|
||||
`11110011,00001111,11000010,{Mod}{xmmreg}{R_m},{imm8}:cmpss {imm8},{Mod}{R_m},{xmmreg}
|
||||
')dnl
|
||||
00001111,1011000{w},{mod}{reg}{r_m}:cmpxchg{w} {reg},{mod}{r_m}
|
||||
# SPECIAL 00001111,11000111,{mod}001{r_m}:[{rex.w}?cmpxchg16b:cmpxchg8b] {reg},{mod}{r_m}
|
||||
00001111,10100010:cpuid
|
||||
11110011,00001111,11100110,{Mod}{xmmreg}{R_m}:cvtdq2pd {Mod}{R_m},{xmmreg}
|
||||
00001111,01011011,{Mod}{xmmreg}{R_m}:cvtdq2ps {Mod}{R_m},{xmmreg}
|
||||
11110010,00001111,11100110,{Mod}{xmmreg}{R_m}:cvtpd2dq {Mod}{R_m},{xmmreg}
|
||||
01100110,00001111,01011010,{Mod}{xmmreg}{R_m}:cvtpd2ps {Mod}{R_m},{xmmreg}
|
||||
01100110,00001111,00101010,{MOD}{xmmreg}{R_M}:cvtpi2pd {MOD}{R_M},{xmmreg}
|
||||
00001111,00101010,{MOD}{xmmreg}{R_M}:{R}INVALID {MOD}{R_M},{xmmreg}
|
||||
01100110,00001111,01011011,{Mod}{xmmreg}{R_m}:cvtps2dq {Mod}{R_m},{xmmreg}
|
||||
00001111,01011010,{Mod}{xmmreg}{R_m}:cvtps2pd {Mod}{R_m},{xmmreg}
|
||||
11110010,00001111,01011010,{Mod}{xmmreg}{R_m}:cvtsd2ss {Mod}{R_m},{xmmreg}
|
||||
11110010,00001111,00101010,{mod}{xmmreg}{r_m}:cvtsi2sd {mod}{r_m},{xmmreg}
|
||||
11110011,00001111,00101010,{mod}{xmmreg}{r_m}:cvtsi2ss {mod}{r_m},{xmmreg}
|
||||
11110011,00001111,01011010,{Mod}{xmmreg}{R_m}:cvtss2sd {Mod}{R_m},{xmmreg}
|
||||
01100110,00001111,11100110,{Mod}{xmmreg}{R_m}:cvttpd2dq {Mod}{R_m},{xmmreg}
|
||||
11110011,00001111,01011011,{Mod}{mmxreg}{R_m}:cvttps2dq {Mod}{R_m},{mmxreg}
|
||||
ifdef(`i386',
|
||||
`00100111:daa
|
||||
00101111:das
|
||||
')dnl
|
||||
1111111{w},{mod}001{r_m}:dec{w} {mod}{r_m}{w}
|
||||
ifdef(`i386',
|
||||
`01001{reg}:dec {reg}
|
||||
')dnl
|
||||
1111011{w},{mod}110{r_m}:div{w} {mod}{r_m}{w}
|
||||
01100110,00001111,01011110,{Mod}{xmmreg}{R_m}:divpd {Mod}{R_m},{xmmreg}
|
||||
00001111,01011110,{Mod}{xmmreg}{R_m}:divps {Mod}{R_m},{xmmreg}
|
||||
11110010,00001111,01011110,{Mod}{xmmreg}{R_m}:divsd {Mod}{R_m},{xmmreg}
|
||||
11110011,00001111,01011110,{Mod}{xmmreg}{R_m}:divss {Mod}{R_m},{xmmreg}
|
||||
00001111,01110111:emms
|
||||
11001000,{imm16},{imm8}:enter {imm16},{imm8}
|
||||
11011001,11010000:fnop
|
||||
11011001,11100000:fchs
|
||||
11011001,11100001:fabs
|
||||
11011001,11100100:ftst
|
||||
11011001,11100101:fxam
|
||||
11011001,11101000:fld1
|
||||
11011001,11101001:fldl2t
|
||||
11011001,11101010:fldl2e
|
||||
11011001,11101011:fldpi
|
||||
11011001,11101100:fldlg2
|
||||
11011001,11101101:fldln2
|
||||
11011001,11101110:fldz
|
||||
11011001,11110000:f2xm1
|
||||
11011001,11110001:fyl2x
|
||||
11011001,11110010:fptan
|
||||
11011001,11110011:fpatan
|
||||
11011001,11110100:fxtract
|
||||
11011001,11110101:fprem1
|
||||
11011001,11110110:fdecstp
|
||||
11011001,11110111:fincstp
|
||||
11011001,11111000:fprem
|
||||
11011001,11111001:fyl2xp1
|
||||
11011001,11111010:fsqrt
|
||||
11011001,11111011:fsincos
|
||||
11011001,11111100:frndint
|
||||
11011001,11111101:fscale
|
||||
11011001,11111110:fsin
|
||||
11011001,11111111:fcos
|
||||
# ORDER
|
||||
11011000,11000{freg}:fadd {freg},%st
|
||||
11011100,11000{freg}:fadd %st,{freg}
|
||||
11011{D}00,{mod}000{r_m}:fadd{D} {mod}{r_m}
|
||||
# ORDER END
|
||||
# ORDER
|
||||
11011000,11001{freg}:fmul {freg},%st
|
||||
11011100,11001{freg}:fmul %st,{freg}
|
||||
11011{D}00,{mod}001{r_m}:fmul{D} {mod}{r_m}
|
||||
# ORDER END
|
||||
# ORDER
|
||||
11011000,11100{freg}:fsub {freg},%st
|
||||
11011100,11100{freg}:fsub %st,{freg}
|
||||
11011{D}00,{mod}100{r_m}:fsub{D} {mod}{r_m}
|
||||
# ORDER END
|
||||
# ORDER
|
||||
11011000,11101{freg}:fsubr {freg},%st
|
||||
11011100,11101{freg}:fsubr %st,{freg}
|
||||
11011{D}00,{mod}101{r_m}:fsubr{D} {mod}{r_m}
|
||||
# ORDER END
|
||||
# ORDER
|
||||
11011101,11010{freg}:fst {freg}
|
||||
11011{D}01,{mod}010{r_m}:fst{D} {mod}{r_m}
|
||||
# ORDER END
|
||||
# ORDER
|
||||
11011101,11011{freg}:fstp {freg}
|
||||
11011{D}01,{mod}011{r_m}:fstp{D} {mod}{r_m}
|
||||
# ORDER END
|
||||
11011001,{mod}100{r_m}:fldenv {mod}{r_m}
|
||||
11011001,{mod}101{r_m}:fldcw {mod}{r_m}
|
||||
11011001,{mod}110{r_m}:fnstenv {mod}{r_m}
|
||||
11011001,{mod}111{r_m}:fnstcw {mod}{r_m}
|
||||
11011001,11001{freg}:fxch {freg}
|
||||
# ORDER
|
||||
11011110,11000{freg}:faddp %st,{freg}
|
||||
ifdef(`ASSEMBLER',
|
||||
`11011110,11000001:faddp
|
||||
')dnl
|
||||
# ORDER
|
||||
11011010,11000{freg}:fcmovb {freg},%st
|
||||
11011{w1}10,{mod}000{r_m}:fiadd{w1} {mod}{r_m}
|
||||
# ORDER END
|
||||
# ORDER
|
||||
11011010,11001{freg}:fcmove {freg},%st
|
||||
11011110,11001{freg}:fmulp %st,{freg}
|
||||
11011{w1}10,{mod}001{r_m}:fimul{w1} {mod}{r_m}
|
||||
# ORDER END
|
||||
# ORDER
|
||||
11011110,11100{freg}:fsubp %st,{freg}
|
||||
11011{w1}10,{mod}100{r_m}:fisub{w1} {mod}{r_m}
|
||||
# ORDER END
|
||||
# ORDER
|
||||
11011110,11101{freg}:fsubrp %st,{freg}
|
||||
11011{w1}10,{mod}101{r_m}:fisubr{w1} {mod}{r_m}
|
||||
# ORDER END
|
||||
# ORDER
|
||||
11011111,11100000:fnstsw %ax
|
||||
11011111,{mod}100{r_m}:fbld {mod}{r_m}
|
||||
# ORDER END
|
||||
# ORDER
|
||||
11011111,11110{freg}:fcomip {freg},%st
|
||||
11011111,{mod}110{r_m}:fbstp {mod}{r_m}
|
||||
# ORDER END
|
||||
11011001,11100000:fchs
|
||||
# ORDER
|
||||
10011011,11011011,11100010:fclex
|
||||
10011011,11011011,11100011:finit
|
||||
10011011:fwait
|
||||
# END ORDER
|
||||
11011011,11100010:fnclex
|
||||
11011010,11000{freg}:fcmovb {freg},%st
|
||||
11011010,11001{freg}:fcmove {freg},%st
|
||||
11011010,11010{freg}:fcmovbe {freg},%st
|
||||
11011010,11011{freg}:fcmovu {freg},%st
|
||||
11011011,11000{freg}:fcmovnb {freg},%st
|
||||
11011011,11001{freg}:fcmovne {freg},%st
|
||||
11011011,11010{freg}:fcmovnbe {freg},%st
|
||||
11011011,11011{freg}:fcmovnu {freg},%st
|
||||
# ORDER
|
||||
11011000,11010{freg}:fcom {freg}
|
||||
ifdef(`ASSEMBLER',
|
||||
`11011000,11010001:fcom
|
||||
')dnl
|
||||
11011{D}00,{mod}010{r_m}:fcom{D} {mod}{r_m}
|
||||
# END ORDER
|
||||
# ORDER
|
||||
11011000,11011{freg}:fcomp {freg}
|
||||
ifdef(`ASSEMBLER',
|
||||
`11011000,11011001:fcomp
|
||||
')dnl
|
||||
11011{D}00,{mod}011{r_m}:fcomp{D} {mod}{r_m}
|
||||
# END ORDER
|
||||
11011110,11011001:fcompp
|
||||
11011011,11110{freg}:fcomi {freg},%st
|
||||
11011111,11110{freg}:fcomip {freg},%st
|
||||
11011011,11101{freg}:fucomi {freg},%st
|
||||
11011111,11101{freg}:fucomip {freg},%st
|
||||
11011001,11111111:fcos
|
||||
11011001,11110110:fdecstp
|
||||
# ORDER
|
||||
11011000,11110{freg}:fdiv {freg},%st
|
||||
11011100,11110{freg}:fdiv %st,{freg}
|
||||
11011{D}00,{mod}110{r_m}:fdiv{D} {mod}{r_m}
|
||||
# END ORDER
|
||||
11011010,{mod}110{r_m}:fidivl {mod}{r_m}
|
||||
# ORDER
|
||||
11011110,11110{freg}:fdivp %st,{freg}
|
||||
11011110,{mod}110{r_m}:fidiv {mod}{r_m}
|
||||
# END ORDER
|
||||
11011110,11111{freg}:fdivrp %st,{freg}
|
||||
ifdef(`ASSEMBLER',
|
||||
`11011110,11111001:fdivp
|
||||
')dnl
|
||||
# ORDER
|
||||
11011000,11111{freg}:fdivr {freg},%st
|
||||
11011100,11111{freg}:fdivr %st,{freg}
|
||||
11011{D}00,{mod}111{r_m}:fdivr{D} {mod}{r_m}
|
||||
# END ORDER
|
||||
11011010,{mod}111{r_m}:fidivrl {mod}{r_m}
|
||||
11011110,{mod}111{r_m}:fidivr {mod}{r_m}
|
||||
11011110,11110{freg}:fdivrp %st,{freg}
|
||||
ifdef(`ASSEMBLER',
|
||||
`11011110,11110001:fdivrp
|
||||
')dnl
|
||||
11011101,11000{freg}:ffree {freg}
|
||||
11011010,11010{freg}:fcmovbe {freg}
|
||||
11011{w1}10,{mod}010{r_m}:ficom{w1} {mod}{r_m}
|
||||
11011010,11011{freg}:fcmovu {freg}
|
||||
11011{w1}10,{mod}011{r_m}:ficomp{w1} {mod}{r_m}
|
||||
11011111,{mod}000{r_m}:fild {mod}{r_m}
|
||||
11011011,{mod}000{r_m}:fildl {mod}{r_m}
|
||||
11011111,{mod}101{r_m}:fildll {mod}{r_m}
|
||||
11011001,11110111:fincstp
|
||||
11011011,11100011:fninit
|
||||
11011{w1}11,{mod}010{r_m}:fist{w1} {mod}{r_m}
|
||||
11011{w1}11,{mod}011{r_m}:fistp{w1} {mod}{r_m}
|
||||
11011111,{mod}111{r_m}:fistpll {mod}{r_m}
|
||||
11011{w1}11,{mod}001{r_m}:fisttp{w1} {mod}{r_m}
|
||||
11011101,{mod}001{r_m}:fisttpll {mod}{r_m}
|
||||
11011011,{mod}101{r_m}:fldt {mod}{r_m}
|
||||
11011011,{mod}111{r_m}:fstpt {mod}{r_m}
|
||||
# ORDER
|
||||
11011001,11000{freg}:fld {freg}
|
||||
11011{D}01,{mod}000{r_m}:fld{D} {mod}{r_m}
|
||||
# ORDER END
|
||||
# ORDER
|
||||
11011101,11100{freg}:fucom {freg}
|
||||
11011101,{mod}100{r_m}:frstor {mod}{r_m}
|
||||
# ORDER END
|
||||
11011101,11101{freg}:fucomp {freg}
|
||||
11011101,{mod}110{r_m}:fnsave {mod}{r_m}
|
||||
11011101,{mod}111{r_m}:fnstsw {mod}{r_m}
|
||||
#
|
||||
#
|
||||
#
|
||||
11110100:hlt
|
||||
1111011{w},{mod}111{r_m}:idiv{w} {mod}{r_m}{w}
|
||||
1111011{w},{mod}101{r_m}:imul{w} {mod}{r_m}{w}
|
||||
00001111,10101111,{mod}{reg}{r_m}:imul {reg},{mod}{r_m}
|
||||
011010{s}1,{mod}{reg}{r_m},{imm}:imul {imm}{s},{mod}{r_m},{reg}
|
||||
1110010{w},{imm8}:in {imm8},{ax}{w}
|
||||
1110110{w}:in {dx},{ax}{w}
|
||||
1111111{w},{mod}000{r_m}:inc{w} {mod}{r_m}{w}
|
||||
01000{reg}:inc {reg}
|
||||
0110110{w}:{R}ins{w} {dx},{es_di}
|
||||
11001101,{imm8}:int {imm8}
|
||||
11001100:int3
|
||||
11001110:into
|
||||
00001111,00001000:invd
|
||||
# ORDER
|
||||
00001111,00000001,11111000:swapgs
|
||||
00001111,00000001,{mod}111{r_m}:invlpg {mod}{r_m}
|
||||
# ORDER END
|
||||
11001111:iret{W}
|
||||
0111{tttn},{disp8}:j{tttn} {disp8}
|
||||
00001111,1000{tttn},{rel}:j{tttn} {rel}
|
||||
00001111,1001{tttn},{mod}000{8r_m}:set{tttn} {mod}{8r_m}
|
||||
# SPECIAL 11100011,{disp8}:[{dpfx}?jcxz:jecxz] {disp8}
|
||||
11100011,{disp8}:INVALID {disp8}
|
||||
11101011,{disp8}:jmp {disp8}
|
||||
11101001,{rel}:jmp {rel}
|
||||
11111111,{mod}100{r_m}:jmp *{mod}{r_m}
|
||||
11101010,{absval},{sel}:ljmp {sel},{absval}
|
||||
11111111,{mod}101{r_m}:ljmp *{mod}{r_m}
|
||||
10011111:lahf
|
||||
00001111,00000010,{mod}{reg}{16r_m}:lar {mod}{16r_m},{reg}
|
||||
11000101,{mod}{reg}{r_m}:lds {mod}{r_m},{reg}
|
||||
10001101,{mod}{reg}{r_m}:lea {mod}{r_m},{reg}
|
||||
11001001:leave
|
||||
11000100,{mod}{reg}{r_m}:les {mod}{r_m},{reg}
|
||||
00001111,10110100,{mod}{reg}{r_m}:lfs {mod}{r_m},{reg}
|
||||
00001111,00000001,{mod}010{r_m}:lgdt{w0} {mod}{r_m}
|
||||
00001111,10110101,{mod}{reg}{r_m}:lgs {mod}{r_m},{reg}
|
||||
00001111,00000001,{mod}011{r_m}:lidt{w0} {mod}{r_m}
|
||||
00001111,00000000,{mod}010{16r_m}:lldt {mod}{16r_m}
|
||||
00001111,00000001,{mod}110{16r_m}:lmsw {mod}{16r_m}
|
||||
11110000:lock
|
||||
1010110{w}:{R}lods {ds_si},{ax}{w}
|
||||
11100010,{disp8}:loop {disp8}
|
||||
11100001,{disp8}:loope {disp8}
|
||||
11100000,{disp8}:loopne {disp8}
|
||||
00001111,00000011,{mod}{reg}{16r_m}:lsl {mod}{16r_m},{reg}
|
||||
00001111,10110010,{mod}{reg}{r_m}:lss {mod}{r_m},{reg}
|
||||
00001111,00000000,{mod}011{16r_m}:ltr {mod}{16r_m}
|
||||
1000100{w},{mod}{reg}{r_m}:mov {reg}{w},{mod}{r_m}{w}
|
||||
1000101{w},{mod}{reg}{r_m}:mov {mod}{r_m}{w},{reg}{w}
|
||||
1100011{w},{mod}000{r_m},{imm}:mov{w} {imm}{w},{mod}{r_m}{w}
|
||||
1011{w}{reg},{imm}:mov {imm}{w},{reg}{w}
|
||||
1010000{w},{abs}:mov {abs},{ax}{w}
|
||||
1010001{w},{abs}:mov {ax}{w},{abs}
|
||||
00001111,00100000,11{ccc}{reg}:mov {ccc},{reg}
|
||||
00001111,00100010,11{ccc}{reg}:mov {reg},{ccc}
|
||||
00001111,00100001,11{ddd}{reg}:mov {ddd},{reg}
|
||||
00001111,00100011,11{ddd}{reg}:mov {reg},{ddd}
|
||||
10001100,{mod}{sreg3}{r_m}:mov {sreg3},{mod}{r_m}
|
||||
10001110,{mod}{sreg3}{r_m}:mov {mod}{r_m},{sreg3}
|
||||
1010010{w}:{R}movs{w} {ds_si},{es_di}
|
||||
00001111,1011111{w},{mod}{reg}{r_m}:movsx{w} {mod}{r_m},{reg}
|
||||
00001111,1011011{w},{mod}{reg}{r_m}:movzx{w} {mod}{r_m},{reg}
|
||||
1111011{w},{mod}100{r_m}:mul{w} {mod}{r_m}{w}
|
||||
1111011{w},{mod}011{r_m}:neg{w} {mod}{r_m}{w}
|
||||
ifdef(`ASSEMBLER',
|
||||
`10010000:nop
|
||||
11110011,10010000:pause
|
||||
',
|
||||
`10010000:{R}INVALID
|
||||
')dnl
|
||||
1111011{w},{mod}010{r_m}:not{w} {mod}{r_m}{w}
|
||||
0000100{w},{mod}{reg}{r_m}:or {reg}{w},{mod}{r_m}{w}
|
||||
0000101{w},{mod}{reg}{r_m}:or {mod}{r_m}{w},{reg}{w}
|
||||
1000000{w},{mod}001{r_m},{imm}:or{w} {imm}{w},{mod}{r_m}{w}
|
||||
100000{s}{w},{mod}001{r_m},{imm}:or{w} {imm}{s},{mod}{r_m}{w}
|
||||
0000110{w},{imm}:or {imm}{w},{ax}{w}
|
||||
1110011{w},{imm8}:out {ax}{w},{imm8}
|
||||
1110111{w}:out {ax}{w},{dx}
|
||||
0110111{w}:{R}outs{w} {ds_si},{dx}
|
||||
10001111,{mod}000{r_m}:pop{w} {mod}{r_m}
|
||||
01011{reg}:pop {reg}
|
||||
00001111,10{sreg3}001:pop {sreg3}
|
||||
01100001:popa{W}
|
||||
10011101:popf{W}
|
||||
11111111,{mod}110{r_m}:push{w} {mod}{r_m}
|
||||
01010{reg}:push {reg}
|
||||
011010{s}0,{imm}:push {imm}{s}
|
||||
000{sreg2}110:push {sreg2}
|
||||
00001111,10{sreg3}000:push {sreg3}
|
||||
01100000:pusha{W}
|
||||
10011100:pushf{W}
|
||||
1101000{w},{mod}010{r_m}:rcl{w} {mod}{r_m}{w}
|
||||
1101001{w},{mod}010{r_m}:rcl{w} %cl,{mod}{r_m}{w}
|
||||
1100000{w},{mod}010{r_m},{imm8}:rcl{w} {imm8},{mod}{r_m}{w}
|
||||
1101000{w},{mod}011{r_m}:rcr{w} {mod}{r_m}{w}
|
||||
1101001{w},{mod}011{r_m}:rcr{w} %cl,{mod}{r_m}{w}
|
||||
1100000{w},{mod}011{r_m},{imm8}:rcr{w} {imm8},{mod}{r_m}{w}
|
||||
00001111,00110010:rdmsr
|
||||
00001111,00110011:rdpmc
|
||||
00001111,00110001:rdtsc
|
||||
11000011:ret
|
||||
11000010,{imm16}:ret {imm16}
|
||||
11001011:lret
|
||||
11001010,{imm16}:lret {imm16}
|
||||
1101000{w},{mod}000{r_m}:rol{w} {mod}{r_m}{w}
|
||||
1101001{w},{mod}000{r_m}:rol{w} %cl,{mod}{r_m}{w}
|
||||
1100000{w},{mod}000{r_m},{imm8}:rol{w} {imm8},{mod}{r_m}{w}
|
||||
1101000{w},{mod}001{r_m}:ror{w} {mod}{r_m}{w}
|
||||
1101001{w},{mod}001{r_m}:ror{w} %cl,{mod}{r_m}{w}
|
||||
1100000{w},{mod}001{r_m},{imm8}:ror{w} {imm8},{mod}{r_m}{w}
|
||||
00001111,10101010:rsm
|
||||
10011110:sahf
|
||||
1101000{w},{mod}111{r_m}:sar{w} {mod}{r_m}{w}
|
||||
1101001{w},{mod}111{r_m}:sar{w} %cl,{mod}{r_m}{w}
|
||||
1100000{w},{mod}111{r_m},{imm8}:sar{w} {imm8},{mod}{r_m}{w}
|
||||
0001100{w},{mod}{reg}{r_m}:sbb {reg}{w},{mod}{r_m}{w}
|
||||
0001101{w},{mod}{reg}{r_m}:sbb {mod}{r_m}{w},{reg}{w}
|
||||
0001110{w},{imm}:sbb {imm}{w},{ax}{w}
|
||||
1000000{w},{mod}011{r_m},{imm}:sbb{w} {imm}{w},{mod}{r_m}{w}
|
||||
1000001{w},{mod}011{r_m},{imms}:sbb{w} {imms},{mod}{r_m}
|
||||
1010111{w}:{RE}scas {es_di},{ax}{w}
|
||||
00001111,1001{tttn},{mod}000{r_m}:set{tttn} {mod}{r_m}
|
||||
1101000{w},{mod}100{r_m}:shl{w} {mod}{r_m}{w}
|
||||
1101001{w},{mod}100{r_m}:shl{w} %cl,{mod}{r_m}{w}
|
||||
1100000{w},{mod}100{r_m},{imm8}:shl{w} {imm8},{mod}{r_m}{w}
|
||||
1101000{w},{mod}101{r_m}:shr{w} {mod}{r_m}{w}
|
||||
00001111,10100100,{mod}{reg}{r_m},{imm8}:shld {imm8},{reg},{mod}{r_m}
|
||||
00001111,10100101,{mod}{reg}{r_m}:shld %cl,{reg},{mod}{r_m}
|
||||
1101001{w},{mod}101{r_m}:shr{w} %cl,{mod}{r_m}{w}
|
||||
1100000{w},{mod}101{r_m},{imm8}:shr{w} {imm8},{mod}{r_m}{w}
|
||||
00001111,10101100,{mod}{reg}{r_m},{imm8}:shrd {imm8},{reg},{mod}{r_m}
|
||||
00001111,10101101,{mod}{reg}{r_m}:shrd %cl,{reg},{mod}{r_m}
|
||||
# ORDER
|
||||
00001111,00000001,11000001:vmcall
|
||||
00001111,00000001,11000010:vmlaunch
|
||||
00001111,00000001,11000011:vmresume
|
||||
00001111,00000001,11000100:vmxoff
|
||||
00001111,00000001,{mod}000{r_m}:sgdtl {mod}{r_m}
|
||||
# ORDER END
|
||||
# ORDER
|
||||
00001111,00000001,11001000:monitor %eax,%ecx,%edx
|
||||
00001111,00000001,11001001:mwait %eax,%ecx
|
||||
00001111,00000001,{mod}001{r_m}:sidtl {mod}{r_m}
|
||||
# ORDER END
|
||||
00001111,00000000,{mod}000{r_m}:sldt {mod}{r_m}
|
||||
00001111,00000001,{mod}100{r_m}:smsw {mod}{r_m}
|
||||
11111001:stc
|
||||
11111101:std
|
||||
11111011:sti
|
||||
1010101{w}:{R}stos {ax}{w},{es_di}
|
||||
00001111,00000000,{mod}001{r_m}:str {mod}{r_m}
|
||||
0010100{w},{mod}{reg}{r_m}:sub {reg}{w},{mod}{r_m}{w}
|
||||
0010101{w},{mod}{reg}{r_m}:sub {mod}{r_m}{w},{reg}{w}
|
||||
0010110{w},{imm}:sub {imm}{w},{ax}{w}
|
||||
1000000{w},{mod}101{r_m},{imm}:sub{w} {imm}{w},{mod}{r_m}{w}
|
||||
1000001{w},{mod}101{r_m},{imms}:sub{w} {imms},{mod}{r_m}
|
||||
1000010{w},{mod}{reg}{r_m}:test {reg}{w},{mod}{r_m}{w}
|
||||
1010100{w},{imm}:test {imm}{w},{ax}{w}
|
||||
1111011{w},{mod}000{r_m},{imm}:test{w} {imm}{w},{mod}{r_m}{w}
|
||||
00001111,00001011:ud2a
|
||||
00001111,00000000,{mod}100{16r_m}:verr {mod}{16r_m}
|
||||
00001111,00000000,{mod}101{16r_m}:verw {mod}{16r_m}
|
||||
00001111,00001001:wbinvd
|
||||
00001111,00001101,{mod}000{8r_m}:prefetch {mod}{8r_m}
|
||||
00001111,00001101,{mod}001{8r_m}:prefetchw {mod}{8r_m}
|
||||
00001111,00011000,{mod}000{r_m}:prefetchnta {mod}{r_m}
|
||||
00001111,00011000,{mod}001{r_m}:prefetcht0 {mod}{r_m}
|
||||
00001111,00011000,{mod}010{r_m}:prefetcht1 {mod}{r_m}
|
||||
00001111,00011000,{mod}011{r_m}:prefetcht2 {mod}{r_m}
|
||||
00001111,00011111,{mod}{reg}{r_m}:nop{w} {mod}{r_m}
|
||||
dnl without prefix: movups
|
||||
dnl with 0xf3: movss
|
||||
dnl with 0x66: movupd
|
||||
dnl with 0xf2: movsd
|
||||
00001111,00010000,{Mod}{xmmreg}{R_m}:{R}INVALID {Mod}{R_m},{xmmreg}
|
||||
00001111,00010001,{Mod}{xmmreg}{R_m}:{R}INVALID {xmmreg},{Mod}{R_m}
|
||||
00001111,00110000:wrmsr
|
||||
00001111,1100000{w},{mod}{reg}{r_m}:xadd{w} {reg},{mod}{r_m}
|
||||
1000011{w},{mod}{reg}{r_m}:xchg {reg}{w},{mod}{r_m}{w}
|
||||
10010{reg}:xchg {ax},{reg}
|
||||
11010111:xlat {ds_bx}
|
||||
0011000{w},{mod}{reg}{r_m}:xor {reg}{w},{mod}{r_m}{w}
|
||||
0011001{w},{mod}{reg}{r_m}:xor {mod}{r_m}{w},{reg}{w}
|
||||
0011010{w},{imm}:xor {imm}{w},{ax}{w}
|
||||
1000000{w},{mod}110{r_m},{imm}:xor{w} {imm}{w},{mod}{r_m}{w}
|
||||
1000001{w},{mod}110{r_m},{imms}:xor{w} {imms},{mod}{r_m}
|
||||
00001111,01110111:emms
|
||||
00001111,01101110,{mod}{mmxreg}{r_m}:movd {mod}{r_m},{mmxreg}
|
||||
00001111,01111110,{mod}{mmxreg}{r_m}:movd {mmxreg},{mod}{r_m}
|
||||
00001111,01101111,{MOD}{mmxreg}{R_M}:movq {MOD}{R_M},{mmxreg}
|
||||
00001111,01111111,{MOD}{mmxreg}{R_M}:movq {mmxreg},{MOD}{R_M}
|
||||
00001111,01101011,{MOD}{mmxreg}{R_M}:packssdw {MOD}{R_M},{mmxreg}
|
||||
00001111,01100011,{MOD}{mmxreg}{R_M}:packsswb {MOD}{R_M},{mmxreg}
|
||||
00001111,01100111,{MOD}{mmxreg}{R_M}:packuswb {MOD}{R_M},{mmxreg}
|
||||
00001111,111111{gg},{MOD}{mmxreg}{R_M}:padd{gg} {MOD}{R_M},{mmxreg}
|
||||
00001111,111111{0g},{MOD}{mmxreg}{R_M}:padds{0g} {MOD}{R_M},{mmxreg}
|
||||
00001111,110111{0g},{MOD}{mmxreg}{R_M}:paddus{0g} {MOD}{R_M},{mmxreg}
|
||||
00001111,11011011,{MOD}{mmxreg}{R_M}:pand {MOD}{R_M},{mmxreg}
|
||||
00001111,11011111,{MOD}{mmxreg}{R_M}:pandn {MOD}{R_M},{mmxreg}
|
||||
00001111,011101{gg},{MOD}{mmxreg}{R_M}:pcmpeq{gg} {MOD}{R_M},{mmxreg}
|
||||
00001111,011001{gg},{MOD}{mmxreg}{R_M}:pcmpgt{gg} {MOD}{R_M},{mmxreg}
|
||||
00001111,11110101,{MOD}{mmxreg}{R_M}:pmaddwd {MOD}{R_M},{mmxreg}
|
||||
00001111,11100101,{MOD}{mmxreg}{R_M}:pmulhw {MOD}{R_M},{mmxreg}
|
||||
00001111,11010101,{MOD}{mmxreg}{R_M}:pmullw {MOD}{R_M},{mmxreg}
|
||||
00001111,11101011,{MOD}{mmxreg}{R_M}:por {MOD}{R_M},{mmxreg}
|
||||
00001111,111100{GG},{MOD}{mmxreg}{R_M}:psll{GG} {MOD}{R_M},{mmxreg}
|
||||
00001111,011100{GG},11110{mmxreg},{imm8}:psll{GG} {imm8},{mmxreg}
|
||||
00001111,111000{gG},{MOD}{mmxreg}{R_M}:psra{gG} {MOD}{R_M},{mmxreg}
|
||||
00001111,011100{gG},11100{mmxreg},{imm8}:psra{gG} {imm8},{mmxreg}
|
||||
00001111,110100{GG},{MOD}{mmxreg}{R_M}:psrl{GG} {MOD}{R_M},{mmxreg}
|
||||
00001111,011100{GG},11010{mmxreg},{imm8}:psrl{GG} {imm8},{mmxreg}
|
||||
00001111,111110{gg},{MOD}{mmxreg}{R_M}:psub{gg} {MOD}{R_M},{mmxreg}
|
||||
00001111,111010{0g},{MOD}{mmxreg}{R_M}:psubs{0g} {MOD}{R_M},{mmxreg}
|
||||
00001111,110110{0g},{MOD}{mmxreg}{R_M}:psubus{0g} {MOD}{R_M},{mmxreg}
|
||||
00001111,011010{gg},{MOD}{mmxreg}{R_M}:punpckh{gg} {MOD}{R_M},{mmxreg}
|
||||
00001111,011000{gg},{MOD}{mmxreg}{R_M}:punpckl{gg} {MOD}{R_M},{mmxreg}
|
||||
00001111,11101111,{MOD}{mmxreg}{R_M}:pxor {MOD}{R_M},{mmxreg}
|
||||
00001111,01011000,{Mod}{xmmreg}{R_m}:addps {Mod}{R_m},{xmmreg}
|
||||
11110011,00001111,01011000,{Mod}{xmmreg}{R_m}:addss {Mod}{R_m},{xmmreg}
|
||||
00001111,01010101,{Mod}{xmmreg}{R_m}:andnps {Mod}{R_m},{xmmreg}
|
||||
00001111,01010100,{Mod}{xmmreg}{R_m}:andps {Mod}{R_m},{xmmreg}
|
||||
00001111,11000010,{Mod}{xmmreg}{R_m},00000000:cmpeqps {Mod}{R_m},{xmmreg}
|
||||
00001111,11000010,{Mod}{xmmreg}{R_m},00000001:cmpltps {Mod}{R_m},{xmmreg}
|
||||
00001111,11000010,{Mod}{xmmreg}{R_m},00000010:cmpleps {Mod}{R_m},{xmmreg}
|
||||
00001111,11000010,{Mod}{xmmreg}{R_m},00000011:cmpunordps {Mod}{R_m},{xmmreg}
|
||||
00001111,11000010,{Mod}{xmmreg}{R_m},00000100:cmpneqps {Mod}{R_m},{xmmreg}
|
||||
00001111,11000010,{Mod}{xmmreg}{R_m},00000101:cmpnltps {Mod}{R_m},{xmmreg}
|
||||
00001111,11000010,{Mod}{xmmreg}{R_m},00000110:cmpnleps {Mod}{R_m},{xmmreg}
|
||||
00001111,11000010,{Mod}{xmmreg}{R_m},00000111:cmpordps {Mod}{R_m},{xmmreg}
|
||||
11110011,00001111,11000010,{Mod}{xmmreg}{R_m},00000000:cmpeqss {Mod}{R_m},{xmmreg}
|
||||
11110011,00001111,11000010,{Mod}{xmmreg}{R_m},00000001:cmpltss {Mod}{R_m},{xmmreg}
|
||||
11110011,00001111,11000010,{Mod}{xmmreg}{R_m},00000010:cmpless {Mod}{R_m},{xmmreg}
|
||||
11110011,00001111,11000010,{Mod}{xmmreg}{R_m},00000011:cmpunordss {Mod}{R_m},{xmmreg}
|
||||
11110011,00001111,11000010,{Mod}{xmmreg}{R_m},00000100:cmpneqss {Mod}{R_m},{xmmreg}
|
||||
11110011,00001111,11000010,{Mod}{xmmreg}{R_m},00000101:cmpnltss {Mod}{R_m},{xmmreg}
|
||||
11110011,00001111,11000010,{Mod}{xmmreg}{R_m},00000110:cmpnless {Mod}{R_m},{xmmreg}
|
||||
11110011,00001111,11000010,{Mod}{xmmreg}{R_m},00000111:cmpordss {Mod}{R_m},{xmmreg}
|
||||
00001111,00101010,{MOD}{xmmreg}{R_M}:cvtpi2ps {MOD}{R_M},{xmmreg}
|
||||
11110011,00001111,00101010,{mod}{xmmreg}{r_m}:cvtsi2ss {mod}{r_m},{xmmreg}
|
||||
00001111,01011110,{Mod}{xmmreg}{R_m}:divps {Mod}{R_m},{xmmreg}
|
||||
11110011,00001111,01011110,{Mod}{xmmreg}{R_m}:divss {Mod}{R_m},{xmmreg}
|
||||
00001111,10101110,{mod}001{r_m}:fxrstor {mod}{r_m}
|
||||
00001111,10101110,{mod}000{r_m}:fxsave {mod}{r_m}
|
||||
00001111,10101110,{mod}010{r_m}:ldmxcsr {mod}{r_m}
|
||||
00001111,01011111,{Mod}{xmmreg}{R_m}:maxps {Mod}{R_m},{xmmreg}
|
||||
11110011,00001111,01011111,{Mod}{xmmreg}{R_m}:maxss {Mod}{R_m},{xmmreg}
|
||||
00001111,01011101,{Mod}{xmmreg}{R_m}:minps {Mod}{R_m},{xmmreg}
|
||||
11110011,00001111,01011101,{Mod}{xmmreg}{R_m}:minss {Mod}{R_m},{xmmreg}
|
||||
00001111,00101000,{Mod}{xmmreg}{R_m}:INVALID {Mod}{R_m},{xmmreg}
|
||||
00001111,00101001,{Mod}{xmmreg}{R_m}:INVALID {xmmreg},{Mod}{R_m}
|
||||
00001111,00010010,{Mod}{xmmreg}{R_m}:{R}INVALID {Mod}{R_m},{xmmreg}
|
||||
00001111,00010011,{Mod}{xmmreg}{R_m}:INVALID {xmmreg},{Mod}{R_m}
|
||||
00001111,00010100,{Mod}{xmmreg}{R_m}:INVALID {Mod}{R_m},{xmmreg}
|
||||
00001111,00010101,{Mod}{xmmreg}{R_m}:INVALID {Mod}{R_m},{xmmreg}
|
||||
00001111,00010110,{Mod}{xmmreg}{R_m}:{R}INVALID {Mod}{R_m},{xmmreg}
|
||||
00001111,00010111,{Mod}{xmmreg}{R_m}:INVALID {xmmreg},{Mod}{R_m}
|
||||
00001111,00101011,{mod}{xmmreg}{r_m}:INVALID {xmmreg},{mod}{r_m}
|
||||
00001111,00101100,{Mod}{mmxreg2}{R_m}:{R}INVALID {Mod}{R_m},{mmxreg2}
|
||||
00001111,00101101,{Mod}{mmxreg2}{R_m}:{R}INVALID {Mod}{R_m},{mmxreg2}
|
||||
00001111,00101110,{Mod}{xmmreg}{R_m}:INVALID {Mod}{R_m},{xmmreg}
|
||||
00001111,00101111,{Mod}{xmmreg}{R_m}:INVALID {Mod}{R_m},{xmmreg}
|
||||
00001111,00110111:getsec
|
||||
00001111,01010000,11{reg}{xmmreg}:INVALID {xmmreg},{reg}
|
||||
00001111,01010001,{Mod}{xmmreg}{R_m}:{R}INVALID {Mod}{R_m},{xmmreg}
|
||||
00001111,01010010,{Mod}{xmmreg}{R_m}:{R}INVALID {Mod}{R_m},{xmmreg}
|
||||
00001111,01010011,{Mod}{xmmreg}{R_m}:{R}INVALID {Mod}{R_m},{xmmreg}
|
||||
# ORDER:
|
||||
dnl Many previous entries depend on this being last.
|
||||
000{sreg2}111:pop {sreg2}
|
||||
# ORDER END:
|
||||
@@ -0,0 +1,74 @@
|
||||
{imm} only parameter:
|
||||
- is {s} in opcode: {s} == 0, unsigned (8/)16/32 bit immediate
|
||||
{s} == 1, signed 8 bit immediate
|
||||
|
||||
{es:di}: segment register normally %es, can be overwritten
|
||||
edi/di depending on apfx
|
||||
|
||||
{ds:si}: segment register normally %ds, can be overwritten
|
||||
esi/si depending on apfx
|
||||
|
||||
{ax} al/ax/eax depending of dpfx and w
|
||||
|
||||
{dx} (%edx) or (%dx) depending on apfx
|
||||
|
||||
|
||||
{w} 0 = b, 1 = { no dpfx = l, dpfx = w }
|
||||
|
||||
{W} no dpfx = <empty>, dpfx = w
|
||||
{WW} no dpfx = l, dpfx = w
|
||||
|
||||
{R} rep prefix possible
|
||||
{RE} repe or repne prefix possible
|
||||
|
||||
{ccc} CRx registers
|
||||
{ddd} DRx registers
|
||||
|
||||
{gg} 00 = b, 01 = w, 10 = d, 11 = <illegal>
|
||||
{0g} 00 = b, 01 = w, 10 = <illegal>, 11 = <illegal>
|
||||
{GG} 00 = <illegal>, 01 = w, 10 = d, 11 = q
|
||||
{gG} 00 = <illegal>, 01 = w, 10 = d, 11 = <illegal>
|
||||
|
||||
{modr/m} normal registers
|
||||
{MODR/M} MMX registers
|
||||
{ModR/m} XMM registers
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Special opcodes (prefixes):
|
||||
|
||||
|
||||
01100111:{apfx}
|
||||
01100110:{dpfx}
|
||||
|
||||
00101110:{cs}
|
||||
00111110:{ds}
|
||||
00100110:{es}
|
||||
01100100:{fs}
|
||||
01100101:{gs}
|
||||
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
table format
|
||||
|
||||
1bit RE flag
|
||||
1bit R flag
|
||||
16bit mnemonic
|
||||
3bit suffix
|
||||
|
||||
5bit fct
|
||||
2bit string
|
||||
6bit offset1
|
||||
5bit offset2
|
||||
|
||||
4bit fct
|
||||
1bit string
|
||||
6bit offset1
|
||||
4bit offset2
|
||||
|
||||
2bit fct
|
||||
1bit string
|
||||
3bit offset1
|
||||
1bit offset2
|
||||
|
||||
61bit
|
||||
@@ -0,0 +1,341 @@
|
||||
%mask {s} 1
|
||||
%mask {w} 1
|
||||
%mask {D} 1
|
||||
%mask {imm8} 8
|
||||
%mask {imm16} 16
|
||||
%mask {reg} 3
|
||||
%mask {tttn} 4
|
||||
%mask {gg} 2
|
||||
%mask {mod} 2
|
||||
%mask {MOD} 2
|
||||
%mask {r_m} 3
|
||||
%mask {disp8} 8
|
||||
# imm really is 8/16/32 bit depending on the situation.
|
||||
%mask {imm} 8
|
||||
%mask {abs} 32
|
||||
%mask {sel} 16
|
||||
%mask {imm32} 32
|
||||
%mask {dispA} 32
|
||||
%mask {ccc} 3
|
||||
%mask {ddd} 3
|
||||
%mask {sreg3} 3
|
||||
%mask {sreg2} 2
|
||||
%mask {mmxreg} 3
|
||||
%mask {R_M} 3
|
||||
%mask {0g} 2
|
||||
%mask {GG} 2
|
||||
%mask {gG} 2
|
||||
%mask {Mod} 2
|
||||
%mask {xmmreg} 3
|
||||
%mask {R_m} 3
|
||||
%mask {xmmreg1} 3
|
||||
%mask {xmmreg2} 3
|
||||
%mask {mmreg} 3
|
||||
%prefix {R}
|
||||
%prefix {RE}
|
||||
%suffix {W}
|
||||
%suffix {WW}
|
||||
%synonym {xmmreg1} {xmmreg}
|
||||
%synonym {xmmreg2} {xmmreg}
|
||||
|
||||
%%
|
||||
0001010{w},{imm}:adc {imm}{w},{ax}{w}
|
||||
1000000{w},{mod}010{r_m},{imm}:adc{w} {imm},{mod}{r_m}
|
||||
1000001{w},{mod}010{r_m},{imm8}:adc{w} {imm8},{mod}{r_m}
|
||||
0001000{w},{mod}{reg}{r_m}:adc{w} {reg},{mod}{r_m}
|
||||
0001001{w},{mod}{reg}{r_m}:adc{w} {mod}{r_m},{reg}
|
||||
0000010{w},{imm}:add {imm}{w},{ax}{w}
|
||||
1000000{w},{mod}000{r_m},{imm}:add{w} {imm},{mod}{r_m}
|
||||
1000001{w},{mod}000{r_m},{imm8}:add{w} {imm8},{mod}{r_m}
|
||||
0000000{w},{mod}{reg}{r_m}:add {reg}{w},{mod}{r_m}
|
||||
0000001{w},{mod}{reg}{r_m}:add {mod}{r_m},{reg}{w}
|
||||
01100110,00001111,01011000,{Mod}{xmmreg}{R_m}:addpd {Mod}{R_m},{xmmreg}
|
||||
00001111,01011000,{Mod}{xmmreg}{R_m}:addps {Mod}{R_m},{xmmreg}
|
||||
11110010,00001111,01011000,{Mod}{xmmreg}{R_m}:addsd {Mod}{R_m},{xmmreg}
|
||||
11110011,00001111,01011000,{Mod}{xmmreg}{R_m}:addss {Mod}{R_m},{xmmreg}
|
||||
01100110,00001111,11010000,{Mod}{xmmreg}{R_m}:addsubpd {Mod}{R_m},{xmmreg}
|
||||
11110010,00001111,11010000,{Mod}{xmmreg}{R_m}:addsubps {Mod}{R_m},{xmmreg}
|
||||
#
|
||||
#
|
||||
#
|
||||
0010000{w},{mod}{reg}{r_m}:and{w} {reg},{mod}{r_m}
|
||||
0010001{w},{mod}{reg}{r_m}:and{w} {mod}{r_m},{reg}
|
||||
0010010{w},{imm}:and {imm}{w},{ax}{w}
|
||||
100000{s}{w},{mod}100{r_m},{imm}:and{w} {imm}{s},{mod}{r_m}
|
||||
01100011,{mod}{reg}{r_m}:arpl {reg},{mod}{r_m}
|
||||
01100010,{mod}{reg}{r_m}:bound {reg},{mod}{r_m}
|
||||
00001111,10111100,{mod}{reg}{r_m}:bsf {reg},{mod}{r_m}
|
||||
00001111,10111101,{mod}{reg}{r_m}:bsr {reg},{mod}{r_m}
|
||||
00001111,11001{reg}:bswap {reg}
|
||||
00001111,10111010,{mod}100{r_m},{imm8}:bt {imm8},{mod}{r_m}
|
||||
00001111,10100011,{mod}{reg}{r_m}:bt {reg},{mod}{r_m}
|
||||
00001111,10111010,{mod}111{r_m},{imm8}:btc {imm8},{mod}{r_m}
|
||||
00001111,10111011,{mod}{reg}{r_m}:btc {reg},{mod}{r_m}
|
||||
00001111,10111010,{mod}110{r_m},{imm8}:btr {imm8},{mod}{r_m}
|
||||
00001111,10110011,{mod}{reg}{r_m}:btr {reg},{mod}{r_m}
|
||||
00001111,10111010,{mod}101{r_m},{imm8}:bts {imm8},{mod}{r_m}
|
||||
00001111,10101011,{mod}{reg}{r_m}:bts {reg},{mod}{r_m}
|
||||
11101000,{abs}:call {abs}
|
||||
11111111,{mod}010{r_m}:call *{mod}{r_m}
|
||||
10011010,{abs},{sel}:lcall {sel},{abs}
|
||||
11111111,{mod}011{r_m}:lcall {mod}{r_m}
|
||||
10011000:cbt{WW}
|
||||
#SPECIAL 10011001:[{dpfx}?cltd:cwtd]
|
||||
11111000:clc
|
||||
11111100:cld
|
||||
11111010:cli
|
||||
00001111,00000110:clts
|
||||
11110101:cmc
|
||||
00001111,0100{tttn},{mod}{reg}{r_m}:cmov{tttn} {mod}{r_m},{reg}
|
||||
0011100{w},{mod}{reg}{r_m}:cmp{w} {reg},{mod}{r_m}
|
||||
0011101{w},{mod}{reg}{r_m}:cmp{w} {mod}{r_m},{reg}
|
||||
0011110{w},{imm}:cmp {imm}{w},{ax}{w}
|
||||
100000{s}{w},{mod}111{r_m},{imm}:cmp{w} {imm}{s},{mod}{r_m}
|
||||
1010011{w}:{RE}cmps{w}
|
||||
00001111,1011000{w},{mod}{reg}{r_m}:cmpxchg{w} {reg},{mod}{r_m}
|
||||
00001111,11000111,{mod}{reg}{r_m}:cmpxchg8b {reg},{mod}{r_m}
|
||||
00001111,10100010:cpuid
|
||||
00100111:daa
|
||||
00101111:das
|
||||
1111111{w},{mod}001{r_m}:dec{w} {mod}{r_m}
|
||||
01001{reg}:dec {reg}
|
||||
1111011{w},{mod}110{r_m}:div{w} {mod}{r_m}
|
||||
11001000,{imm16},{imm8}:enter {imm16},{imm8}
|
||||
11110100:hlt
|
||||
1111011{w},{mod}111{r_m}:idiv{w} {mod}{r_m}
|
||||
1111011{w},{mod}101{r_m}:imul{w} {mod}{r_m}
|
||||
00001111,10101111,{mod}{reg}{r_m}:imul {reg},{mod}{r_m}
|
||||
011010{s}1,{mod}{reg}{r_m},{imm}:imul {imm}{s},{mod}{r_m},{reg}
|
||||
1110010{w},{imm8}:in {imm8},{ax}{w}
|
||||
1110110{w}:in {dx},{ax}{w}
|
||||
1111111{w},{mod}000{r_m}:inc{w} {mod}{r_m}
|
||||
01000{reg}:inc {reg}
|
||||
0110110{w}:{R}ins{w} {dx},{es_di}
|
||||
11001101,{imm8}:int {imm8}
|
||||
11001100:int 3
|
||||
11001110:into
|
||||
00001111,00001000:invd
|
||||
00001111,00000001,{mod}111{r_m}:invlpg {mod}{r_m}
|
||||
11001111:iret{W}
|
||||
0111{tttn},{disp8}:j{tttn} {disp8}
|
||||
00001111,1000{tttn},{dispA}:j{tttn} {dispA}
|
||||
#SPECIAL 11100011,{disp8}:[{dpfx}?jcxz:jecxz] {disp8}
|
||||
11101011,{disp8}:jmp {disp8}
|
||||
11101001,{dispA}:jmp {dispA}
|
||||
11111111,{mod}100{r_m}:jmp *{mod}{r_m}
|
||||
11101010,{abs},{sel}:ljmp {sel},{abs}
|
||||
11111111,{mod}101{r_m}:ljmp {mod}{r_m}
|
||||
10011111:lahf
|
||||
00001111,00000010,{mod}{reg}{r_m}:lar {mod}{r_m},{reg}
|
||||
11000101,{mod}{reg}{r_m}:lds {mod}{r_m},{reg}
|
||||
10001101,{mod}{reg}{r_m}:lea {mod}{r_m},{reg}
|
||||
11001001:leave
|
||||
11000100,{mod}{reg}{r_m}:les {mod}{r_m},{reg}
|
||||
00001111,10110100,{mod}{reg}{r_m}:lfs {mod}{r_m},{reg}
|
||||
00001111,00000001,{mod}010{r_m}:lgdt{WW} {mod}{r_m}
|
||||
00001111,10110101,{mod}{reg}{r_m}:lgs {mod}{r_m},{reg}
|
||||
00001111,00000001,{mod}011{r_m}:lidt{WW} {mod}{r_m}
|
||||
00001111,00000000,{mod}010{r_m}:lldt{WW} {mod}{r_m}
|
||||
00001111,00000001,{mod}110{r_m}:lmsw {mod}{r_m}
|
||||
11110000:lock
|
||||
1010110{w}:{R}lods {ds_si},{ax}{w}
|
||||
11100010,{disp8}:loop {disp8}
|
||||
11100001,{disp8}:loope {disp8}
|
||||
11100000,{disp8}:loopne {disp8}
|
||||
00001111,00000011,{mod}{reg}{r_m}:lsl {mod}{r_m},{reg}
|
||||
00001111,10110010,{mod}{reg}{r_m}:lss {mod}{r_m},{reg}
|
||||
00001111,00000000,{mod}011{r_m}:ltr {mod}{r_m}
|
||||
1000100{w},{mod}{reg}{r_m}:mov{w} {reg},{mod}{r_m}
|
||||
1000101{w},{mod}{reg}{r_m}:mov{w} {mod}{r_m},{reg}
|
||||
1100011{w},{mod}000{r_m},{imm}:mov{w} {imm},{mod}{r_m}
|
||||
1011{w}{reg},{imm}:mov{w} {imm},{reg}
|
||||
1010000{w},{abs}:mov {ax}{w},{abs}
|
||||
1010001{w},{abs}:mov {abs},{ax}{w}
|
||||
00001111,00100000,11{ccc}{reg}:mov {reg},{ccc}
|
||||
00001111,00100010,11{ccc}{reg}:mov {ccc},{reg}
|
||||
00001111,00100001,11{ddd}{reg}:mov {reg},{ddd}
|
||||
00001111,00100011,11{ddd}{reg}:mov {ddd},{reg}
|
||||
10001100,{mod}{sreg3}{r_m}:mov {sreg3},{mod}{r_m}
|
||||
10001110,{mod}{sreg3}{r_m}:mov {mod}{r_m},{sreg3}
|
||||
1010010{w}:{R}movs{w} {ds_si},{es_di}
|
||||
00001111,1011111{w},{mod}{reg}{r_m}:movsx{w} {mod}{r_m},{reg}
|
||||
00001111,1011011{w},{mod}{reg}{r_m}:movzx{w} {mod}{r_m},{reg}
|
||||
1111011{w},{mod}100{r_m}:mul{w} {mod}{r_m}
|
||||
1111011{w},{mod}011{r_m}:neg{w} {mod}{r_m}
|
||||
10010000:nop
|
||||
11110011,10010000:pause
|
||||
1111011{w},{mod}010{r_m}:not{w} {mod}{r_m}
|
||||
0000100{w},{mod}{reg}{r_m}:or{w} {reg},{mod}{r_m}
|
||||
0000101{w},{mod}{reg}{r_m}:or{w} {mod}{r_m},{reg}
|
||||
100000{s}{w},{mod}001{r_m},{imm}:or{w} {imm}{s},{mod}{r_m}
|
||||
0000110{w},{imm}:mov {imm}{w},{ax}{w}
|
||||
1110011{w},{imm8}:out {ax}{w},{imm8}
|
||||
1110111{w}:out {ax}{w},{dx}
|
||||
0110111{w}:{R}outs{w} {ds_si},{dx}
|
||||
10001111,{mod}000{r_m}:pop {mod}{r_m}
|
||||
01011{reg}:pop {reg}
|
||||
000{sreg2}111:pop {sreg2}
|
||||
00001111,10{sreg3}001:pop {sreg3}
|
||||
01100001:popa{W}
|
||||
10011101:popf{W}
|
||||
11111111,{mod}110{r_m}:push {mod}{r_m}
|
||||
01010{reg}:push {reg}
|
||||
011010{s}0,{imm}:push {imm}{s}
|
||||
000{sreg2}110:push {sreg2}
|
||||
00001111,10{sreg3}000:push {sreg3}
|
||||
01100000:pusha{W}
|
||||
10011100:pushf{W}
|
||||
1101000{w},{mod}010{r_m}:rcl{w} {mod}{r_m}
|
||||
1101001{w},{mod}010{r_m}:rcl{w} %cl,{mod}{r_m}
|
||||
1100000{w},{mod}010{r_m},{imm8}:rcl{w} {imm8},{mod}{r_m}
|
||||
1101000{w},{mod}011{r_m}:rcr{w} {mod}{r_m}
|
||||
1101001{w},{mod}011{r_m}:rcr{w} %cl,{mod}{r_m}
|
||||
1100000{w},{mod}011{r_m},{imm8}:rcr{w} {imm8},{mod}{r_m}
|
||||
00001111,00110010:rdmsr
|
||||
00001111,00110011:rdpmc
|
||||
00001111,00110001:rdtsc
|
||||
11000011:ret
|
||||
11000010,{imm16}:ret {imm16}
|
||||
11001011:lret
|
||||
11001010,{imm16}:lret {imm16}
|
||||
1101000{w},{mod}000{r_m}:rol{w} {mod}{r_m}
|
||||
1101001{w},{mod}000{r_m}:rol{w} %cl,{mod}{r_m}
|
||||
1100000{w},{mod}000{r_m},{imm8}:rol{w} {imm8},{mod}{r_m}
|
||||
1101000{w},{mod}001{r_m}:ror{w} {mod}{r_m}
|
||||
1101001{w},{mod}001{r_m}:ror{w} %cl,{mod}{r_m}
|
||||
1100000{w},{mod}001{r_m},{imm8}:ror{w} {imm8},{mod}{r_m}
|
||||
00001111,10101010:rsm
|
||||
10011110:sahf
|
||||
1101000{w},{mod}111{r_m}:sar{w} {mod}{r_m}
|
||||
1101001{w},{mod}111{r_m}:sar{w} %cl,{mod}{r_m}
|
||||
1100000{w},{mod}111{r_m},{imm8}:sar{w} {imm8},{mod}{r_m}
|
||||
0001100{w},{mod}{reg}{r_m}:sbb{w} {reg},{mod}{r_m}
|
||||
0001101{w},{mod}{reg}{r_m}:sbb{w} {mod}{r_m},{reg}
|
||||
0001110{w},{imm}:sbb {imm}{w},{ax}{w}
|
||||
100000{s}{w},{mod}011{r_m},{imm}:sbb{w} {imm}{s},{mod}{r_m}
|
||||
1010111{w}:{RE}scas {es_di},{ax}{w}
|
||||
00001111,1001{tttn},{mod}000{r_m}:set{tttn} {mod}{r_m}
|
||||
00001111,00000001,{mod}000{r_m}:sgdt {mod}{r_m}
|
||||
1101000{w},{mod}100{r_m}:shl{w} {mod}{r_m}
|
||||
1101001{w},{mod}100{r_m}:shl{w} %cl,{mod}{r_m}
|
||||
1100000{w},{mod}100{r_m},{imm8}:shl{w} {imm8},{mod}{r_m}
|
||||
1101000{w},{mod}101{r_m}:shr{w} {mod}{r_m}
|
||||
00001111,10100100,{mod}{reg}{r_m},{imm8}:shld {imm8},{reg},{mod}{r_m}
|
||||
00001111,10100101,{mod}{reg}{r_m}:shld %cl,{reg},{mod}{r_m}
|
||||
1101001{w},{mod}101{r_m}:shr{w} %cl,{mod}{r_m}
|
||||
1100000{w},{mod}101{r_m},{imm8}:shr{w} {imm8},{mod}{r_m}
|
||||
00001111,10101100,{mod}{reg}{r_m},{imm8}:shrd {imm8},{reg},{mod}{r_m}
|
||||
00001111,10101101,{mod}{reg}{r_m}:shrd %cl,{reg},{mod}{r_m}
|
||||
00001111,00000001,{mod}001{r_m}:sidt {mod}{r_m}
|
||||
00001111,00000000,{mod}000{r_m}:sldt {mod}{r_m}
|
||||
00001111,00000001,{mod}100{r_m}:smsw {mod}{r_m}
|
||||
11111001:stc
|
||||
11111101:std
|
||||
11111011:sti
|
||||
1010101{w}:{R}stos {ax}{w},{es_di}
|
||||
00001111,00000000,{mod}001{r_m}:str {mod}{r_m}
|
||||
0010100{w},{mod}{reg}{r_m}:sub{w} {reg},{mod}{r_m}
|
||||
0010101{w},{mod}{reg}{r_m}:sub{w} {mod}{r_m},{reg}
|
||||
0010110{w},{imm}:sub {imm}{w},{ax}{w}
|
||||
100000{s}{w},{mod}101{r_m},{imm}:sub{w} {imm}{s},{mod}{r_m}
|
||||
1000010{w},{mod}{reg}{r_m}:test{w} {reg},{mod}{r_m}{w}
|
||||
1000011{w},{mod}{reg}{r_m}:test{w} {mod}{r_m}{w},{reg}
|
||||
0010100{w},{imm}:test {imm}{w},{ax}{w}
|
||||
1111011{w},{mod}000{r_m},{imm}:test{w} {imm},{mod}{r_m}
|
||||
00001111,00001011:ud2a
|
||||
00001111,00000000,{mod}100{r_m}:verr {mod}{r_m}
|
||||
00001111,00000000,{mod}101{r_m}:verw {mod}{r_m}
|
||||
10011011:wait
|
||||
00001111,00001001:wbinvd
|
||||
00001111,00110000:wrmsr
|
||||
00001111,1100000{w},{mod}{reg}{r_m}:xadd{w} {reg},{mod}{r_m}
|
||||
1000011{w},{mod}{reg}{r_m}:xchg{w} {reg},{mod}{r_m}
|
||||
11010111:xlat
|
||||
0011000{w},{mod}{reg}{r_m}:xor{w} {reg},{mod}{r_m}
|
||||
0011001{w},{mod}{reg}{r_m}:xor{w} {mod}{r_m},{reg}
|
||||
0011010{w},{imm}:xor {imm}{w},{ax}{w}
|
||||
100000{s}{w},{mod}110{r_m},{imm}:xor{w} {imm}{s},{mod}{r_m}
|
||||
00001111,01110111:emms
|
||||
00001111,01101110,{mod}{mmxreg}{r_m}:movd {mod}{r_m},{mmxreg}
|
||||
00001111,01111110,{mod}{mmxreg}{r_m}:movd {mmxreg},{mod}{r_m}
|
||||
00001111,01101111,{MOD}{mmxreg}{R_M}:movq {MOD}{R_M},{mmxreg}
|
||||
00001111,01111111,{MOD}{mmxreg}{R_M}:movq {mmxreg},{MOD}{R_M}
|
||||
00001111,01101011,{MOD}{mmxreg}{R_M}:packssdw {MOD}{R_M},{mmxreg}
|
||||
00001111,01100011,{MOD}{mmxreg}{R_M}:packsswb {MOD}{R_M},{mmxreg}
|
||||
00001111,01100111,{MOD}{mmxreg}{R_M}:packuswb {MOD}{R_M},{mmxreg}
|
||||
00001111,111111{gg},{MOD}{mmxreg}{R_M}:padd{gg} {MOD}{R_M},{mmxreg}
|
||||
00001111,111111{0g},{MOD}{mmxreg}{R_M}:padds{0g} {MOD}{R_M},{mmxreg}
|
||||
00001111,110111{0g},{MOD}{mmxreg}{R_M}:paddus{0g} {MOD}{R_M},{mmxreg}
|
||||
00001111,11011011,{MOD}{mmxreg}{R_M}:pand {MOD}{R_M},{mmxreg}
|
||||
00001111,11011111,{MOD}{mmxreg}{R_M}:pandn {MOD}{R_M},{mmxreg}
|
||||
00001111,011101{gg},{MOD}{mmxreg}{R_M}:pcmpeq{gg} {MOD}{R_M},{mmxreg}
|
||||
00001111,011001{gg},{MOD}{mmxreg}{R_M}:pcmpgt{gg} {MOD}{R_M},{mmxreg}
|
||||
00001111,11110101,{MOD}{mmxreg}{R_M}:pmaddwd {MOD}{R_M},{mmxreg}
|
||||
00001111,11100101,{MOD}{mmxreg}{R_M}:pmulhw {MOD}{R_M},{mmxreg}
|
||||
00001111,11010101,{MOD}{mmxreg}{R_M}:pmullw {MOD}{R_M},{mmxreg}
|
||||
00001111,11101011,{MOD}{mmxreg}{R_M}:por {MOD}{R_M},{mmxreg}
|
||||
00001111,111100{GG},{MOD}{mmxreg}{R_M}:psll{GG} {MOD}{R_M},{mmxreg}
|
||||
00001111,011100{GG},11110{mmxreg},{imm8}:psll{GG} {imm8},{mmxreg}
|
||||
00001111,111000{gG},{MOD}{mmxreg}{R_M}:psra{gG} {MOD}{R_M},{mmxreg}
|
||||
00001111,011100{gG},11100{mmxreg},{imm8}:psra{gG} {imm8},{mmxreg}
|
||||
00001111,110100{GG},{MOD}{mmxreg}{R_M}:psrl{GG} {MOD}{R_M},{mmxreg}
|
||||
00001111,011100{GG},11010{mmxreg},{imm8}:psrl{GG} {imm8},{mmxreg}
|
||||
00001111,111110{gg},{MOD}{mmxreg}{R_M}:psub{gg} {MOD}{R_M},{mmxreg}
|
||||
00001111,111010{0g},{MOD}{mmxreg}{R_M}:psubs{0g} {MOD}{R_M},{mmxreg}
|
||||
00001111,110110{0g},{MOD}{mmxreg}{R_M}:psubus{0g} {MOD}{R_M},{mmxreg}
|
||||
00001111,011010{gg},{MOD}{mmxreg}{R_M}:punpckh{gg} {MOD}{R_M},{mmxreg}
|
||||
00001111,011000{gg},{MOD}{mmxreg}{R_M}:punpckl{gg} {MOD}{R_M},{mmxreg}
|
||||
00001111,11101111,{MOD}{mmxreg}{R_M}:pxor {MOD}{R_M},{mmxreg}
|
||||
00001111,01011000,{Mod}{xmmreg}{R_m}:addps {Mod}{R_m},{xmmreg}
|
||||
11110011,00001111,01011000,{Mod}{xmmreg}{R_m}:addss {Mod}{R_m},{xmmreg}
|
||||
00001111,01010101,{Mod}{xmmreg}{R_m}:andnps {Mod}{R_m},{xmmreg}
|
||||
00001111,01010100,{Mod}{xmmreg}{R_m}:andps {Mod}{R_m},{xmmreg}
|
||||
00001111,11000010,{Mod}{xmmreg}{R_m},00000000:cmpeqps {Mod}{R_m},{xmmreg}
|
||||
00001111,11000010,{Mod}{xmmreg}{R_m},00000001:cmpltps {Mod}{R_m},{xmmreg}
|
||||
00001111,11000010,{Mod}{xmmreg}{R_m},00000010:cmpleps {Mod}{R_m},{xmmreg}
|
||||
00001111,11000010,{Mod}{xmmreg}{R_m},00000011:cmpunordps {Mod}{R_m},{xmmreg}
|
||||
00001111,11000010,{Mod}{xmmreg}{R_m},00000100:cmpneqps {Mod}{R_m},{xmmreg}
|
||||
00001111,11000010,{Mod}{xmmreg}{R_m},00000101:cmpnltps {Mod}{R_m},{xmmreg}
|
||||
00001111,11000010,{Mod}{xmmreg}{R_m},00000110:cmpnleps {Mod}{R_m},{xmmreg}
|
||||
00001111,11000010,{Mod}{xmmreg}{R_m},00000111:cmpordps {Mod}{R_m},{xmmreg}
|
||||
11110011,00001111,11000010,{Mod}{xmmreg}{R_m},00000000:cmpeqss {Mod}{R_m},{xmmreg}
|
||||
11110011,00001111,11000010,{Mod}{xmmreg}{R_m},00000001:cmpltss {Mod}{R_m},{xmmreg}
|
||||
11110011,00001111,11000010,{Mod}{xmmreg}{R_m},00000010:cmpless {Mod}{R_m},{xmmreg}
|
||||
11110011,00001111,11000010,{Mod}{xmmreg}{R_m},00000011:cmpunordss {Mod}{R_m},{xmmreg}
|
||||
11110011,00001111,11000010,{Mod}{xmmreg}{R_m},00000100:cmpneqss {Mod}{R_m},{xmmreg}
|
||||
11110011,00001111,11000010,{Mod}{xmmreg}{R_m},00000101:cmpnltss {Mod}{R_m},{xmmreg}
|
||||
11110011,00001111,11000010,{Mod}{xmmreg}{R_m},00000110:cmpnless {Mod}{R_m},{xmmreg}
|
||||
11110011,00001111,11000010,{Mod}{xmmreg}{R_m},00000111:cmpordss {Mod}{R_m},{xmmreg}
|
||||
00001111,00101111,{Mod}{xmmreg}{R_m}:comiss {Mod}{R_m},{xmmreg}
|
||||
00001111,00101010,{MOD}{xmmreg}{R_M}:cvtpi2ps {MOD}{R_M},{xmmreg}
|
||||
00001111,00101101,{MOD}{mmreg}{R_M}:cvtps2pi {MOD}{R_M},{mmreg}
|
||||
11110011,00001111,00101010,{mod}{xmmreg}{r_m}:cvtsi2ss {mod}{r_m},{xmmreg}
|
||||
11110011,00001111,00101101,{Mod}{reg}{R_m}:cvtss2si {Mod}{R_m},{reg}
|
||||
00001111,00101100,{Mod}{mmreg}{R_m}:cvttps2pi {Mod}{R_m},{mmreg}
|
||||
11110011,00001111,00101100,{Mod}{reg}{R_m}:cvttss2si {Mod}{R_m},{reg}
|
||||
00001111,01011110,{Mod}{xmmreg}{R_m}:divps {Mod}{R_m},{xmmreg}
|
||||
11110011,00001111,01011110,{Mod}{xmmreg}{R_m}:divss {Mod}{R_m},{xmmreg}
|
||||
00001111,10101110,{mod}001{r_m}:fxrstor {mod}{r_m}
|
||||
00001111,10101110,{mod}000{r_m}:fxsave {mod}{r_m}
|
||||
00001111,10101110,{mod}010{r_m}:ldmxcsr {mod}{r_m}
|
||||
00001111,01011111,{Mod}{xmmreg}{R_m}:maxps {Mod}{R_m},{xmmreg}
|
||||
11110011,00001111,01011111,{Mod}{xmmreg}{R_m}:maxss {Mod}{R_m},{xmmreg}
|
||||
00001111,01011101,{Mod}{xmmreg}{R_m}:minps {Mod}{R_m},{xmmreg}
|
||||
11110011,00001111,01011101,{Mod}{xmmreg}{R_m}:minss {Mod}{R_m},{xmmreg}
|
||||
00001111,00101000,{Mod}{xmmreg}{R_m}:movaps {Mod}{R_m},{xmmreg}
|
||||
00001111,00101001,{Mod}{xmmreg}{R_m}:movaps {xmmreg},{Mod}{R_m}
|
||||
# ORDER:
|
||||
00001111,00010010,11{xmmreg1}{xmmreg2}:movhlps {xmmreg1},{xmmreg2}
|
||||
00001111,00010011,11{xmmreg1}{xmmreg2}:movhlps {xmmreg2},{xmmreg1}
|
||||
00001111,00010010,{Mod}{xmmreg}{R_m}:movlps {Mod}{R_m},{xmmreg}
|
||||
00001111,00010011,{Mod}{xmmreg}{R_m}:movlps {xmmreg},{Mod}{R_m}
|
||||
# ORDER END:
|
||||
# ORDER:
|
||||
00001111,00010110,11{xmmreg1}{xmmreg2}:movlhps {xmmreg1},{xmmreg2}
|
||||
00001111,00010111,11{xmmreg1}{xmmreg2}:movlhps {xmmreg2},{xmmreg1}
|
||||
00001111,00010110,{Mod}{xmmreg}{R_m}:movhps {Mod}{R_m},{xmmreg}
|
||||
00001111,00010111,{Mod}{xmmreg}{R_m}:movhps {xmmreg},{Mod}{R_m}
|
||||
# ORDER END:
|
||||
# BOGUS
|
||||
00000000,11{reg}111:fadd {reg}
|
||||
00001111,00000001,11000001:vmcall
|
||||
+1406
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,914 @@
|
||||
#include <assert.h>
|
||||
#include <config.h>
|
||||
#include <ctype.h>
|
||||
#include <endian.h>
|
||||
#include <errno.h>
|
||||
#include <gelf.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#include "../libebl/libeblP.h"
|
||||
|
||||
#define MACHINE_ENCODING __LITTLE_ENDIAN
|
||||
#include "memory-access.h"
|
||||
|
||||
|
||||
#ifndef MNEFILE
|
||||
# define MNEFILE "i386.mnemonics"
|
||||
#endif
|
||||
|
||||
#define MNESTRFIELD(line) MNESTRFIELD1 (line)
|
||||
#define MNESTRFIELD1(line) str##line
|
||||
static const union mnestr_t
|
||||
{
|
||||
struct
|
||||
{
|
||||
#define MNE(name) char MNESTRFIELD (__LINE__)[sizeof (#name)];
|
||||
#include MNEFILE
|
||||
#undef MNE
|
||||
};
|
||||
char str[0];
|
||||
} mnestr =
|
||||
{
|
||||
{
|
||||
#define MNE(name) #name,
|
||||
#include MNEFILE
|
||||
#undef MNE
|
||||
}
|
||||
};
|
||||
|
||||
/* The index can be stored in the instrtab. */
|
||||
enum
|
||||
{
|
||||
#define MNE(name) MNE_##name,
|
||||
#include MNEFILE
|
||||
#undef MNE
|
||||
MNE_INVALID
|
||||
};
|
||||
|
||||
static const unsigned short int mneidx[] =
|
||||
{
|
||||
#define MNE(name) \
|
||||
[MNE_##name] = offsetof (union mnestr_t, MNESTRFIELD (__LINE__)),
|
||||
#include MNEFILE
|
||||
#undef MNE
|
||||
};
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
idx_cs = 0,
|
||||
idx_ds,
|
||||
idx_es,
|
||||
idx_fs,
|
||||
idx_gs,
|
||||
idx_ss,
|
||||
idx_data16,
|
||||
idx_addr16,
|
||||
idx_rep,
|
||||
idx_repne,
|
||||
idx_lock
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
#define prefbit(pref) has_##pref = 1 << idx_##pref
|
||||
prefbit (cs),
|
||||
prefbit (ds),
|
||||
prefbit (es),
|
||||
prefbit (fs),
|
||||
prefbit (gs),
|
||||
prefbit (ss),
|
||||
prefbit (data16),
|
||||
prefbit (addr16),
|
||||
prefbit (rep),
|
||||
prefbit (repne),
|
||||
prefbit (lock)
|
||||
#undef prefbit
|
||||
};
|
||||
#define SEGMENT_PREFIXES \
|
||||
(has_cs | has_ds | has_es | has_fs | has_gs | has_ss)
|
||||
|
||||
#define prefix_cs 0x2e
|
||||
#define prefix_ds 0x3e
|
||||
#define prefix_es 0x26
|
||||
#define prefix_fs 0x64
|
||||
#define prefix_gs 0x65
|
||||
#define prefix_ss 0x36
|
||||
#define prefix_data16 0x66
|
||||
#define prefix_addr16 0x67
|
||||
#define prefix_rep 0xf3
|
||||
#define prefix_repne 0xf2
|
||||
#define prefix_lock 0xf0
|
||||
|
||||
|
||||
static const uint8_t known_prefixes[] =
|
||||
{
|
||||
#define newpref(pref) [idx_##pref] = prefix_##pref
|
||||
newpref (cs),
|
||||
newpref (ds),
|
||||
newpref (es),
|
||||
newpref (fs),
|
||||
newpref (gs),
|
||||
newpref (ss),
|
||||
newpref (data16),
|
||||
newpref (addr16),
|
||||
newpref (rep),
|
||||
newpref (repne),
|
||||
newpref (lock)
|
||||
#undef newpref
|
||||
};
|
||||
#define nknown_prefixes (sizeof (known_prefixes) / sizeof (known_prefixes[0]))
|
||||
|
||||
|
||||
#if 0
|
||||
static const char *prefix_str[] =
|
||||
{
|
||||
#define newpref(pref) [idx_##pref] = #pref
|
||||
newpref (cs),
|
||||
newpref (ds),
|
||||
newpref (es),
|
||||
newpref (fs),
|
||||
newpref (gs),
|
||||
newpref (ss),
|
||||
newpref (data16),
|
||||
newpref (addr16),
|
||||
newpref (rep),
|
||||
newpref (repne),
|
||||
newpref (lock)
|
||||
#undef newpref
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef DISFILE
|
||||
# define DISFILE "i386_dis.h"
|
||||
#endif
|
||||
#include DISFILE
|
||||
|
||||
|
||||
#define ADD_CHAR(ch) \
|
||||
do { \
|
||||
if (unlikely (bufcnt == bufsize)) \
|
||||
goto enomem; \
|
||||
buf[bufcnt++] = (ch); \
|
||||
} while (0)
|
||||
|
||||
#define ADD_STRING(str) \
|
||||
do { \
|
||||
const char *_str = (str); \
|
||||
size_t _len = strlen (_str); \
|
||||
if (unlikely (bufcnt + _len > bufsize)) \
|
||||
goto enomem; \
|
||||
memcpy (buf + bufcnt, str, _len); \
|
||||
bufcnt += _len; \
|
||||
} while (0)
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
int
|
||||
i386_disasm (const uint8_t **startp, const uint8_t *end, GElf_Addr addr,
|
||||
const char *fmt, DisasmOutputCB_t outcb, DisasmGetSymCB_t symcb,
|
||||
void *outcbarg, void *symcbarg)
|
||||
{
|
||||
const char *save_fmt = fmt;
|
||||
|
||||
while (1)
|
||||
{
|
||||
#define BUFSIZE 512
|
||||
const size_t bufsize = BUFSIZE;
|
||||
char initbuf[BUFSIZE];
|
||||
char *buf = initbuf;
|
||||
size_t bufcnt = 0;
|
||||
|
||||
int prefixes = 0;
|
||||
|
||||
const uint8_t *data = *startp;
|
||||
const uint8_t *begin = data;
|
||||
|
||||
fmt = save_fmt;
|
||||
|
||||
/* Recognize all prefixes. */
|
||||
while (data < end)
|
||||
{
|
||||
unsigned int i;
|
||||
for (i = 0; i < nknown_prefixes; ++i)
|
||||
if (known_prefixes[i] == *data)
|
||||
break;
|
||||
if (i == nknown_prefixes)
|
||||
break;
|
||||
|
||||
prefixes |= 1 << i;
|
||||
|
||||
++data;
|
||||
}
|
||||
|
||||
assert (data <= end);
|
||||
if (data == end)
|
||||
{
|
||||
if (prefixes != 0)
|
||||
goto print_prefix;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
const uint8_t *curr = match_data;
|
||||
const uint8_t *const match_end = match_data + sizeof (match_data);
|
||||
|
||||
enomem:
|
||||
;
|
||||
|
||||
size_t cnt = 0;
|
||||
while (curr < match_end)
|
||||
{
|
||||
const uint8_t *const start = curr;
|
||||
|
||||
uint_fast8_t len = *curr++;
|
||||
|
||||
assert (len > 0);
|
||||
assert (curr + 2 * len + 2 <= match_end);
|
||||
|
||||
const uint8_t *codep = data;
|
||||
size_t avail = len;
|
||||
|
||||
do
|
||||
{
|
||||
uint_fast8_t masked = *codep++ & *curr++;
|
||||
if (masked != *curr++)
|
||||
break;
|
||||
|
||||
--avail;
|
||||
if (codep == end && avail > 0)
|
||||
return 0;
|
||||
}
|
||||
while (avail > 0);
|
||||
|
||||
if (avail != 0)
|
||||
{
|
||||
not:
|
||||
curr = start + 1 + 2 * len + 2;
|
||||
++cnt;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (len > end - data)
|
||||
/* 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;
|
||||
|
||||
size_t prefix_size = 0;
|
||||
|
||||
// XXXonly print as prefix if valid?
|
||||
if ((prefixes & has_lock) != 0)
|
||||
{
|
||||
ADD_STRING ("lock ");
|
||||
prefix_size += 5;
|
||||
}
|
||||
|
||||
if (instrtab[cnt].rep)
|
||||
{
|
||||
if ((prefixes & has_rep) != 0)
|
||||
{
|
||||
ADD_STRING ("rep ");
|
||||
prefix_size += 4;
|
||||
}
|
||||
}
|
||||
else if (instrtab[cnt].repe
|
||||
&& (prefixes & (has_rep | has_repne)) != 0)
|
||||
{
|
||||
if ((prefixes & has_repne) != 0)
|
||||
{
|
||||
ADD_STRING ("repne ");
|
||||
prefix_size += 6;
|
||||
}
|
||||
else if ((prefixes & has_rep) != 0)
|
||||
{
|
||||
ADD_STRING ("repe ");
|
||||
prefix_size += 5;
|
||||
}
|
||||
}
|
||||
else if ((prefixes & (has_rep | has_repne)) != 0)
|
||||
{
|
||||
uint_fast8_t byte;
|
||||
print_prefix:
|
||||
bufcnt = 0;
|
||||
byte = *begin;
|
||||
/* This is a prefix byte. Print it. */
|
||||
switch (byte)
|
||||
{
|
||||
case prefix_rep:
|
||||
ADD_STRING ("rep");
|
||||
break;
|
||||
case prefix_repne:
|
||||
ADD_STRING ("repne");
|
||||
break;
|
||||
case prefix_cs:
|
||||
ADD_STRING ("cs");
|
||||
break;
|
||||
case prefix_ds:
|
||||
ADD_STRING ("ds");
|
||||
break;
|
||||
case prefix_es:
|
||||
ADD_STRING ("es");
|
||||
break;
|
||||
case prefix_fs:
|
||||
ADD_STRING ("fs");
|
||||
break;
|
||||
case prefix_gs:
|
||||
ADD_STRING ("gs");
|
||||
break;
|
||||
case prefix_ss:
|
||||
ADD_STRING ("ss");
|
||||
break;
|
||||
case prefix_data16:
|
||||
ADD_STRING ("data16");
|
||||
break;
|
||||
case prefix_addr16:
|
||||
ADD_STRING ("addr16");
|
||||
break;
|
||||
case prefix_lock:
|
||||
ADD_STRING ("lock");
|
||||
break;
|
||||
default:
|
||||
/* Cannot happen. */
|
||||
abort ();
|
||||
}
|
||||
data = begin + 1;
|
||||
++addr;
|
||||
|
||||
/* The string definitely fits. */
|
||||
buf[bufcnt++] = '\0';
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* We have a match. First determine how many bytes are
|
||||
needed for the adressing mode. */
|
||||
const uint8_t *param_start = codep;
|
||||
if (instrtab[cnt].modrm)
|
||||
{
|
||||
uint_fast8_t modrm = codep[-1];
|
||||
|
||||
if ((prefixes & has_addr16) == 0)
|
||||
{
|
||||
/* Account for SIB. */
|
||||
if ((modrm & 0xc0) != 0xc0 && (modrm & 0x7) == 0x4)
|
||||
param_start += 1;
|
||||
}
|
||||
|
||||
/* Account for displacement. */
|
||||
if ((modrm & 0xc7) == 5 || (modrm & 0xc0) == 0x80
|
||||
|| ((modrm & 0xc7) == 0x4 && (codep[0] & 0x7) == 0x5))
|
||||
param_start += 4;
|
||||
else if ((modrm & 0xc0) == 0x40)
|
||||
param_start += 1;
|
||||
}
|
||||
|
||||
unsigned long string_end_idx = 0;
|
||||
while (*fmt != '\0')
|
||||
{
|
||||
if (*fmt != '%')
|
||||
{
|
||||
char ch = *fmt++;
|
||||
if (ch == '\\')
|
||||
{
|
||||
switch ((ch = *fmt++))
|
||||
{
|
||||
case '0' ... '7':
|
||||
{
|
||||
int val = ch - '0';
|
||||
ch = *fmt;
|
||||
if (ch >= '0' && ch <= '7')
|
||||
{
|
||||
val *= 8;
|
||||
val += ch - '0';
|
||||
ch = *++fmt;
|
||||
if (ch >= '0' && ch <= '7' && val < 32)
|
||||
{
|
||||
val *= 8;
|
||||
val += ch - '0';
|
||||
++fmt;
|
||||
}
|
||||
}
|
||||
ch = val;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
ch = '\n';
|
||||
break;
|
||||
|
||||
case 't':
|
||||
ch = '\t';
|
||||
break;
|
||||
|
||||
default:
|
||||
return EINVAL;
|
||||
}
|
||||
}
|
||||
ADD_CHAR (ch);
|
||||
continue;
|
||||
}
|
||||
++fmt;
|
||||
|
||||
int width = 0;
|
||||
while (isdigit (*fmt))
|
||||
width = width * 10 + (*fmt++ - '0');
|
||||
|
||||
int prec = 0;
|
||||
if (*fmt == '.')
|
||||
while (isdigit (*++fmt))
|
||||
prec = prec * 10 + (*fmt - '0');
|
||||
|
||||
size_t start_idx = bufcnt;
|
||||
switch (*fmt++)
|
||||
{
|
||||
const char *str;
|
||||
|
||||
case 'm':
|
||||
/* Mnemonic. */
|
||||
|
||||
if (unlikely (instrtab[cnt].mnemonic == MNE_INVALID))
|
||||
{
|
||||
switch (*data)
|
||||
{
|
||||
case 0x90:
|
||||
if (prefixes & ~has_rep)
|
||||
goto print_prefix;
|
||||
/* Discard the 'rep' prefix string possibly
|
||||
already in the buffer. */
|
||||
bufcnt = 0;
|
||||
str = prefixes & has_rep ? "pause" : "nop";
|
||||
break;
|
||||
|
||||
case 0x98:
|
||||
if (prefixes & ~has_data16)
|
||||
goto print_prefix;
|
||||
str = prefixes & has_data16 ? "cbtw" : "cwtl";
|
||||
break;
|
||||
|
||||
case 0x99:
|
||||
if (prefixes & ~has_data16)
|
||||
goto print_prefix;
|
||||
str = prefixes & has_data16 ? "cwtd" : "cltd";
|
||||
break;
|
||||
|
||||
case 0xe3:
|
||||
if (prefixes & ~has_addr16)
|
||||
goto print_prefix;
|
||||
str = prefixes & has_addr16 ? "jcxz" : "jecxz";
|
||||
break;
|
||||
|
||||
case 0x0f:
|
||||
if (data[1] == 0x10 || data[1] == 0x11)
|
||||
{
|
||||
bufcnt = 0;
|
||||
int mod = prefixes & (has_data16 | has_rep
|
||||
| has_repne);
|
||||
if (mod & (mod - 1))
|
||||
return -1;
|
||||
str = (mod & has_data16
|
||||
? "movupd"
|
||||
: mod & has_rep
|
||||
? "movss"
|
||||
: mod & has_repne
|
||||
? "movsd"
|
||||
: "movups");
|
||||
break;
|
||||
}
|
||||
if (data[1] == 0x12)
|
||||
{
|
||||
bufcnt = 0;
|
||||
int mod = prefixes & (has_data16 | has_rep
|
||||
| has_repne);
|
||||
if (mod & (mod - 1))
|
||||
return -1;
|
||||
str = (mod & has_data16
|
||||
? "movlpd"
|
||||
: mod & has_rep
|
||||
? "movsldup"
|
||||
: mod & has_repne
|
||||
? "movddup"
|
||||
: (data[2] & 0xc0) == 0xc0
|
||||
? "movhlps"
|
||||
: "movlps");
|
||||
break;
|
||||
}
|
||||
if (data[1] == 0x13)
|
||||
{
|
||||
bufcnt = 0;
|
||||
int mod = prefixes & has_data16;
|
||||
if (mod & (mod - 1))
|
||||
return -1;
|
||||
str = (mod & has_data16
|
||||
? ((data[2] & 0xc0) == 0xc0
|
||||
? "movhlpd"
|
||||
: "movlpd")
|
||||
: (data[2] & 0xc0) == 0xc0
|
||||
? "movhlps"
|
||||
: "movlps");
|
||||
break;
|
||||
}
|
||||
if (data[1] == 0x14)
|
||||
{
|
||||
bufcnt = 0;
|
||||
int mod = prefixes & has_data16;
|
||||
if (mod & (mod - 1))
|
||||
return -1;
|
||||
str = (mod & has_data16
|
||||
? "unpcklpd" : "unpcklps");
|
||||
break;
|
||||
}
|
||||
if (data[1] == 0x15)
|
||||
{
|
||||
bufcnt = 0;
|
||||
int mod = prefixes & has_data16;
|
||||
if (mod & (mod - 1))
|
||||
return -1;
|
||||
str = (mod & has_data16
|
||||
? "unpckhpd" : "unpckhps");
|
||||
break;
|
||||
}
|
||||
if (data[1] == 0x16)
|
||||
{
|
||||
bufcnt = 0;
|
||||
int mod = prefixes & (has_data16 | has_rep);
|
||||
if (mod & (mod - 1))
|
||||
return -1;
|
||||
str = (mod & has_data16
|
||||
? "movhpd"
|
||||
: mod & has_rep
|
||||
? "movshdup"
|
||||
: (data[2] & 0xc0) == 0xc0
|
||||
? "movlhps"
|
||||
: "movhps");
|
||||
break;
|
||||
}
|
||||
if (data[1] == 0x17)
|
||||
{
|
||||
bufcnt = 0;
|
||||
int mod = prefixes & has_data16;
|
||||
if (mod & (mod - 1))
|
||||
return -1;
|
||||
str = (mod & has_data16
|
||||
? ((data[2] & 0xc0) == 0xc0
|
||||
? "movlhpd" : "movhpd")
|
||||
: (data[2] & 0xc0) == 0xc0
|
||||
? "movlhps"
|
||||
: "movhps");
|
||||
break;
|
||||
}
|
||||
if (data[1] == 0x28 || data[1] == 0x29)
|
||||
{
|
||||
bufcnt = 0;
|
||||
int mod = prefixes & has_data16;
|
||||
if (mod & (mod - 1))
|
||||
return -1;
|
||||
str = (mod & has_data16) ? "movapd" : "movaps";
|
||||
break;
|
||||
}
|
||||
if (data[1] == 0x2a)
|
||||
{
|
||||
bufcnt = 0;
|
||||
int mod = prefixes & (has_data16 | has_rep
|
||||
| has_repne);
|
||||
if (mod & (mod - 1))
|
||||
return -1;
|
||||
str = (mod & has_data16
|
||||
? "cvtpi2pd"
|
||||
: mod & has_rep
|
||||
? "cvtsi2ss"
|
||||
: mod & has_repne
|
||||
? "cvtsi2sd"
|
||||
: "cvtpi2ps");
|
||||
break;
|
||||
}
|
||||
if (data[1] == 0x2b)
|
||||
{
|
||||
bufcnt = 0;
|
||||
int mod = prefixes & has_data16;
|
||||
if (mod & (mod - 1))
|
||||
return -1;
|
||||
prefixes ^= mod;
|
||||
str = (mod & has_data16) ? "movntpd" : "movntps";
|
||||
break;
|
||||
}
|
||||
if (data[1] == 0x2c)
|
||||
{
|
||||
bufcnt = 0;
|
||||
int mod = prefixes & (has_data16 | has_rep
|
||||
| has_repne);
|
||||
if (mod & (mod - 1))
|
||||
return -1;
|
||||
str = (mod & has_data16
|
||||
? "cvttpd2pi"
|
||||
: mod & has_rep
|
||||
? "cvttss2si"
|
||||
: mod & has_repne
|
||||
? "cvttsd2si"
|
||||
: "cvttps2pi");
|
||||
break;
|
||||
}
|
||||
if (data[1] == 0x2d)
|
||||
{
|
||||
bufcnt = 0;
|
||||
int mod = prefixes & (has_data16 | has_rep
|
||||
| has_repne);
|
||||
if (mod & (mod - 1))
|
||||
return -1;
|
||||
str = (mod & has_data16
|
||||
? "cvtpd2pi"
|
||||
: mod & has_rep
|
||||
? "cvtss2si"
|
||||
: mod & has_repne
|
||||
? "cvtsd2si"
|
||||
: "cvtps2pi");
|
||||
break;
|
||||
}
|
||||
if (data[1] == 0x2e)
|
||||
{
|
||||
int mod = prefixes & has_data16;
|
||||
if (mod & (mod - 1))
|
||||
return -1;
|
||||
str = (mod & has_data16
|
||||
? "ucomisd" : "ucomiss");
|
||||
break;
|
||||
}
|
||||
if (data[1] == 0x2f)
|
||||
{
|
||||
int mod = prefixes & has_data16;
|
||||
if (mod & (mod - 1))
|
||||
return -1;
|
||||
str = (mod & has_data16
|
||||
? "comisd" : "comiss");
|
||||
break;
|
||||
}
|
||||
if (data[1] == 0x50)
|
||||
{
|
||||
int mod = prefixes & has_data16;
|
||||
if (mod & (mod - 1))
|
||||
return -1;
|
||||
prefixes ^= mod;
|
||||
str = (mod & has_data16
|
||||
? "movmskpd" : "movmskps");
|
||||
break;
|
||||
}
|
||||
if (data[1] == 0x51)
|
||||
{
|
||||
bufcnt = 0;
|
||||
int mod = prefixes & (has_data16 | has_rep
|
||||
| has_repne);
|
||||
if (mod & (mod - 1))
|
||||
return -1;
|
||||
str = (mod & has_data16
|
||||
? "sqrtpd"
|
||||
: mod & has_rep
|
||||
? "sqrtss"
|
||||
: mod & has_repne
|
||||
? "sqrtsd"
|
||||
: "sqrtps");
|
||||
break;
|
||||
}
|
||||
if (data[1] == 0x52)
|
||||
{
|
||||
bufcnt = 0;
|
||||
int mod = prefixes & has_rep;
|
||||
if (mod & (mod - 1))
|
||||
return -1;
|
||||
str = mod & has_rep ? "rsqrtss" : "rsqrtps";
|
||||
break;
|
||||
}
|
||||
if (data[1] == 0x53)
|
||||
{
|
||||
bufcnt = 0;
|
||||
int mod = prefixes & has_rep;
|
||||
if (mod & (mod - 1))
|
||||
return -1;
|
||||
str = mod & has_rep ? "rcpss" : "rcpps";
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
else
|
||||
str = mnestr.str + mneidx[instrtab[cnt].mnemonic];
|
||||
|
||||
ADD_STRING (str);
|
||||
|
||||
switch (instrtab[cnt].suffix)
|
||||
{
|
||||
case suffix_none:
|
||||
break;
|
||||
case suffix_w:
|
||||
if ((codep[-1] & 0xc0) != 0xc0)
|
||||
{
|
||||
char ch;
|
||||
|
||||
if (data[0] & 1)
|
||||
{
|
||||
if (prefixes & has_data16)
|
||||
ch = 'w';
|
||||
else
|
||||
ch = 'l';
|
||||
}
|
||||
else
|
||||
ch = 'b';
|
||||
|
||||
ADD_CHAR (ch);
|
||||
}
|
||||
break;
|
||||
case suffix_w0:
|
||||
if ((codep[-1] & 0xc0) != 0xc0)
|
||||
ADD_CHAR ('l');
|
||||
break;
|
||||
case suffix_w1:
|
||||
if ((data[0] & 0x4) == 0)
|
||||
ADD_CHAR ('l');
|
||||
break;
|
||||
case suffix_W:
|
||||
if (prefixes & has_data16)
|
||||
{
|
||||
ADD_CHAR ('w');
|
||||
prefixes &= ~has_data16;
|
||||
}
|
||||
#ifdef x86_64
|
||||
else
|
||||
abort ();
|
||||
#endif
|
||||
break;
|
||||
case suffix_tttn:;
|
||||
static const char tttn[16][3] =
|
||||
{
|
||||
"o", "no", "b", "ae", "e", "ne", "be", "a",
|
||||
"s", "ns", "p", "np", "l", "ge", "le", "g"
|
||||
};
|
||||
ADD_STRING (tttn[codep[-1 - instrtab[cnt].modrm] & 0x0f]);
|
||||
break;
|
||||
case suffix_D:
|
||||
if ((codep[-1] & 0xc0) != 0xc0)
|
||||
ADD_CHAR ((data[0] & 0x04) == 0 ? 's' : 'l');
|
||||
break;
|
||||
default:
|
||||
printf("unknown suffix %d\n", instrtab[cnt].suffix);
|
||||
abort ();
|
||||
}
|
||||
|
||||
string_end_idx = bufcnt;
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
if (prec == 1 && instrtab[cnt].fct1 != 0)
|
||||
{
|
||||
/* First parameter. */
|
||||
if (instrtab[cnt].str1 != 0)
|
||||
ADD_STRING (op1_str[instrtab[cnt].str1]);
|
||||
|
||||
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,
|
||||
instrtab[cnt].off1_2 + OFF1_2_BIAS,
|
||||
instrtab[cnt].off1_3 + OFF1_3_BIAS,
|
||||
buf, &bufcnt, bufsize,
|
||||
data, ¶m_start,
|
||||
end,
|
||||
symcb, symcbarg);
|
||||
if (r < 0)
|
||||
goto not;
|
||||
if (r > 0)
|
||||
goto enomem;
|
||||
|
||||
string_end_idx = ~0ul;
|
||||
}
|
||||
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
|
||||
|
||||
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,
|
||||
instrtab[cnt].off2_2 + OFF2_2_BIAS,
|
||||
instrtab[cnt].off2_3 + OFF2_3_BIAS,
|
||||
buf, &bufcnt, bufsize,
|
||||
data, ¶m_start,
|
||||
end,
|
||||
symcb, symcbarg);
|
||||
if (r < 0)
|
||||
goto not;
|
||||
if (r > 0)
|
||||
goto enomem;
|
||||
|
||||
string_end_idx = ~0ul;
|
||||
}
|
||||
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
|
||||
|
||||
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,
|
||||
#ifdef OFF3_2_BITS
|
||||
instrtab[cnt].off3_2 + OFF3_2_BIAS,
|
||||
#else
|
||||
0,
|
||||
#endif
|
||||
#ifdef OFF3_3_BITS
|
||||
instrtab[cnt].off3_3 + OFF3_3_BIAS,
|
||||
#else
|
||||
0,
|
||||
#endif
|
||||
buf, &bufcnt, bufsize,
|
||||
data, ¶m_start,
|
||||
end,
|
||||
symcb, symcbarg);
|
||||
if (r < 0)
|
||||
goto not;
|
||||
if (r > 0)
|
||||
goto enomem;
|
||||
|
||||
string_end_idx = ~0ul;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
/* String end marker. */
|
||||
if (string_end_idx == ~0ul)
|
||||
string_end_idx = bufcnt;
|
||||
/* No padding. */
|
||||
width = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Pad according to the specified width. */
|
||||
while (bufcnt + prefix_size < start_idx + width)
|
||||
ADD_CHAR (' ');
|
||||
prefix_size = 0;
|
||||
}
|
||||
|
||||
if ((prefixes & SEGMENT_PREFIXES) != 0)
|
||||
goto print_prefix;
|
||||
|
||||
if (string_end_idx != ~0ul)
|
||||
buf[string_end_idx] = '\0';
|
||||
|
||||
addr += param_start - begin;
|
||||
data = param_start;
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Invalid (or at least unhandled) opcode. */
|
||||
if (prefixes != 0)
|
||||
goto print_prefix;
|
||||
assert (*startp == data);
|
||||
++data;
|
||||
ADD_STRING ("(bad)");
|
||||
addr += data - begin;
|
||||
|
||||
buf[bufcnt++] = '\0';
|
||||
|
||||
out:
|
||||
*startp = data;
|
||||
int res = outcb (buf, strlen (buf), outcbarg);
|
||||
if (res != 0)
|
||||
return res;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#include <error.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
extern int i386_parse (void);
|
||||
|
||||
|
||||
extern FILE *i386_in;
|
||||
extern int i386_debug;
|
||||
char *infname;
|
||||
|
||||
FILE *outfile;
|
||||
|
||||
int
|
||||
main (int argc, char *argv[argc])
|
||||
{
|
||||
outfile = stdout;
|
||||
|
||||
if (argc == 1)
|
||||
error (EXIT_FAILURE, 0, "usage: %s <MNEDEFFILE>", argv[0]);
|
||||
|
||||
//i386_debug = 1;
|
||||
infname = argv[1];
|
||||
if (strcmp (infname, "-") == 0)
|
||||
i386_in = stdin;
|
||||
else
|
||||
{
|
||||
i386_in = fopen (infname, "r");
|
||||
if (i386_in == NULL)
|
||||
error (EXIT_FAILURE, errno, "cannot open %s", argv[1]);
|
||||
}
|
||||
|
||||
i386_parse ();
|
||||
|
||||
return error_message_count != 0;
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
%{
|
||||
/* Copyright (C) 2004, 2005, 2007 Red Hat, Inc.
|
||||
Written by Ulrich Drepper <drepper@redhat.com>, 2004.
|
||||
|
||||
This program is Open Source software; you can redistribute it and/or
|
||||
modify it under the terms of the Open Software License version 1.0 as
|
||||
published by the Open Source Initiative.
|
||||
|
||||
You should have received a copy of the Open Software License along
|
||||
with this program; if not, you may obtain a copy of the Open Software
|
||||
License version 1.0 from http://www.opensource.org/licenses/osl.php or
|
||||
by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
|
||||
3001 King Ranch Road, Ukiah, CA 95482. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <error.h>
|
||||
#include <libintl.h>
|
||||
|
||||
#include <system.h>
|
||||
#include "i386_parse.h"
|
||||
|
||||
|
||||
static void eat_to_eol (void);
|
||||
static void invalid_char (int ch);
|
||||
%}
|
||||
|
||||
ID [a-zA-Z_][a-zA-Z0-9_/]*
|
||||
ID2 [a-zA-Z0-9_:/]*
|
||||
NUMBER [0-9]+
|
||||
WHITE [[:space:]]+
|
||||
|
||||
%option yylineno
|
||||
%option never-interactive
|
||||
%option noyywrap
|
||||
|
||||
|
||||
%x MAIN
|
||||
|
||||
%%
|
||||
|
||||
"%mask" { return kMASK; }
|
||||
|
||||
"%prefix" { return kPREFIX; }
|
||||
"%suffix" { return kSUFFIX; }
|
||||
|
||||
"%synonym" { return kSYNONYM; }
|
||||
|
||||
{NUMBER} { i386_lval.num = strtoul (yytext, NULL, 10);
|
||||
return kNUMBER; }
|
||||
|
||||
"%%" { BEGIN (MAIN); return kPERCPERC; }
|
||||
|
||||
|
||||
<MAIN>"0" { return '0'; }
|
||||
<MAIN>"1" { return '1'; }
|
||||
|
||||
<INITIAL,MAIN>"{"{ID2}"}" { i386_lval.str = xstrndup (yytext + 1,
|
||||
yyleng - 2);
|
||||
return kBITFIELD; }
|
||||
|
||||
<MAIN>"INVALID" { i386_lval.str = (void *) -1l;
|
||||
return kID; }
|
||||
|
||||
<MAIN>{ID} { i386_lval.str = xstrndup (yytext, yyleng);
|
||||
return kID; }
|
||||
|
||||
<MAIN>"," { return ','; }
|
||||
|
||||
<MAIN>":" { return ':'; }
|
||||
|
||||
<INITIAL,MAIN>^"\n" { /* IGNORE */ }
|
||||
|
||||
<INITIAL,MAIN>"\n" { return '\n'; }
|
||||
|
||||
<INITIAL,MAIN>^"#" { eat_to_eol (); }
|
||||
|
||||
{WHITE} { /* IGNORE */ }
|
||||
|
||||
<MAIN>{WHITE} { return kSPACE; }
|
||||
|
||||
<MAIN>. { i386_lval.ch = *yytext; return kCHAR; }
|
||||
|
||||
. { invalid_char (*yytext); }
|
||||
|
||||
|
||||
%%
|
||||
|
||||
static void
|
||||
eat_to_eol (void)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
int c = input ();
|
||||
|
||||
if (c == EOF || c == '\n')
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
invalid_char (int ch)
|
||||
{
|
||||
error (0, 0, (isascii (ch)
|
||||
? gettext ("invalid character '%c' at line %d; ignored")
|
||||
: gettext ("invalid character '\\%o' at line %d; ignored")),
|
||||
ch, yylineno);
|
||||
}
|
||||
|
||||
// Local Variables:
|
||||
// mode: C
|
||||
// End:
|
||||
+1641
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,168 @@
|
||||
/* Unaligned memory access functionality.
|
||||
Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Red Hat, Inc.
|
||||
Written by Ulrich Drepper <drepper@redhat.com>, 2001.
|
||||
|
||||
This program is Open Source software; you can redistribute it and/or
|
||||
modify it under the terms of the Open Software License version 1.0 as
|
||||
published by the Open Source Initiative.
|
||||
|
||||
You should have received a copy of the Open Software License along
|
||||
with this program; if not, you may obtain a copy of the Open Software
|
||||
License version 1.0 from http://www.opensource.org/licenses/osl.php or
|
||||
by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
|
||||
3001 King Ranch Road, Ukiah, CA 95482. */
|
||||
|
||||
#ifndef _MEMORY_ACCESS_H
|
||||
#define _MEMORY_ACCESS_H 1
|
||||
|
||||
#include <byteswap.h>
|
||||
#include <endian.h>
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
/* When loading this file we require the macro MACHINE_ENCODING to be
|
||||
defined to signal the endianness of the architecture which is
|
||||
defined. */
|
||||
#ifndef MACHINE_ENCODING
|
||||
# error "MACHINE_ENCODING needs to be defined"
|
||||
#endif
|
||||
#if MACHINE_ENCODING != __BIG_ENDIAN && MACHINE_ENCODING != __LITTLE_ENDIAN
|
||||
# error "MACHINE_ENCODING must signal either big or little endian"
|
||||
#endif
|
||||
|
||||
|
||||
/* We use simple memory access functions in case the hardware allows it.
|
||||
The caller has to make sure we don't have alias problems. */
|
||||
#if ALLOW_UNALIGNED
|
||||
|
||||
# define read_2ubyte_unaligned(Addr) \
|
||||
(unlikely (MACHINE_ENCODING != __BYTE_ORDER) \
|
||||
? bswap_16 (*((const uint16_t *) (Addr))) \
|
||||
: *((const uint16_t *) (Addr)))
|
||||
# define read_2sbyte_unaligned(Addr) \
|
||||
(unlikely (MACHINE_ENCODING != __BYTE_ORDER) \
|
||||
? (int16_t) bswap_16 (*((const int16_t *) (Addr))) \
|
||||
: *((const int16_t *) (Addr)))
|
||||
|
||||
# define read_4ubyte_unaligned_noncvt(Addr) \
|
||||
*((const uint32_t *) (Addr))
|
||||
# define read_4ubyte_unaligned(Addr) \
|
||||
(unlikely (MACHINE_ENCODING != __BYTE_ORDER) \
|
||||
? bswap_32 (*((const uint32_t *) (Addr))) \
|
||||
: *((const uint32_t *) (Addr)))
|
||||
# define read_4sbyte_unaligned(Addr) \
|
||||
(unlikely (MACHINE_ENCODING != __BYTE_ORDER) \
|
||||
? (int32_t) bswap_32 (*((const int32_t *) (Addr))) \
|
||||
: *((const int32_t *) (Addr)))
|
||||
|
||||
# define read_8ubyte_unaligned(Addr) \
|
||||
(unlikely (MACHINE_ENCODING != __BYTE_ORDER) \
|
||||
? bswap_64 (*((const uint64_t *) (Addr))) \
|
||||
: *((const uint64_t *) (Addr)))
|
||||
# define read_8sbyte_unaligned(Addr) \
|
||||
(unlikely (MACHINE_ENCODING != __BYTE_ORDER) \
|
||||
? (int64_t) bswap_64 (*((const int64_t *) (Addr))) \
|
||||
: *((const int64_t *) (Addr)))
|
||||
|
||||
#else
|
||||
|
||||
union unaligned
|
||||
{
|
||||
void *p;
|
||||
uint16_t u2;
|
||||
uint32_t u4;
|
||||
uint64_t u8;
|
||||
int16_t s2;
|
||||
int32_t s4;
|
||||
int64_t s8;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
static inline uint16_t
|
||||
read_2ubyte_unaligned (const void *p)
|
||||
{
|
||||
const union unaligned *up = p;
|
||||
if (MACHINE_ENCODING != __BYTE_ORDER)
|
||||
return bswap_16 (up->u2);
|
||||
return up->u2;
|
||||
}
|
||||
static inline int16_t
|
||||
read_2sbyte_unaligned (const void *p)
|
||||
{
|
||||
const union unaligned *up = p;
|
||||
if (MACHINE_ENCODING != __BYTE_ORDER)
|
||||
return (int16_t) bswap_16 (up->u2);
|
||||
return up->s2;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
read_4ubyte_unaligned_noncvt (const void *p)
|
||||
{
|
||||
const union unaligned *up = p;
|
||||
return up->u4;
|
||||
}
|
||||
static inline uint32_t
|
||||
read_4ubyte_unaligned (const void *p)
|
||||
{
|
||||
const union unaligned *up = p;
|
||||
if (MACHINE_ENCODING != __BYTE_ORDER)
|
||||
return bswap_32 (up->u4);
|
||||
return up->u4;
|
||||
}
|
||||
static inline int32_t
|
||||
read_4sbyte_unaligned (const void *p)
|
||||
{
|
||||
const union unaligned *up = p;
|
||||
if (MACHINE_ENCODING != __BYTE_ORDER)
|
||||
return (int32_t) bswap_32 (up->u4);
|
||||
return up->s4;
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
read_8ubyte_unaligned (const void *p)
|
||||
{
|
||||
const union unaligned *up = p;
|
||||
if (MACHINE_ENCODING != __BYTE_ORDER)
|
||||
return bswap_64 (up->u8);
|
||||
return up->u8;
|
||||
}
|
||||
static inline int64_t
|
||||
read_8sbyte_unaligned (const void *p)
|
||||
{
|
||||
const union unaligned *up = p;
|
||||
if (MACHINE_ENCODING != __BYTE_ORDER)
|
||||
return (int64_t) bswap_64 (up->u8);
|
||||
return up->s8;
|
||||
}
|
||||
|
||||
#endif /* allow unaligned */
|
||||
|
||||
|
||||
#define read_2ubyte_unaligned_inc(Addr) \
|
||||
({ uint16_t t_ = read_2ubyte_unaligned (Addr); \
|
||||
Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 2); \
|
||||
t_; })
|
||||
#define read_2sbyte_unaligned_inc(Addr) \
|
||||
({ int16_t t_ = read_2sbyte_unaligned (Addr); \
|
||||
Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 2); \
|
||||
t_; })
|
||||
|
||||
#define read_4ubyte_unaligned_inc(Addr) \
|
||||
({ uint32_t t_ = read_4ubyte_unaligned (Addr); \
|
||||
Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 4); \
|
||||
t_; })
|
||||
#define read_4sbyte_unaligned_inc(Addr) \
|
||||
({ int32_t t_ = read_4sbyte_unaligned (Addr); \
|
||||
Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 4); \
|
||||
t_; })
|
||||
|
||||
#define read_8ubyte_unaligned_inc(Addr) \
|
||||
({ uint64_t t_ = read_8ubyte_unaligned (Addr); \
|
||||
Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 8); \
|
||||
t_; })
|
||||
#define read_8sbyte_unaligned_inc(Addr) \
|
||||
({ int64_t t_ = read_8sbyte_unaligned (Addr); \
|
||||
Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 8); \
|
||||
t_; })
|
||||
|
||||
#endif /* memory-access.h */
|
||||
@@ -0,0 +1,5 @@
|
||||
#define i386_disasm x86_64_disasm
|
||||
#define DISFILE "x86_64_dis.h"
|
||||
#define MNEFILE "x86_64.mnemonics"
|
||||
#define X86_64
|
||||
#include "i386_disasm.c"
|
||||
+1
-1
@@ -34,7 +34,7 @@ AM_CFLAGS += -fpic -Wall -Wshadow -Werror -Wunused -Wextra -Wformat=2 \
|
||||
-std=gnu99
|
||||
|
||||
INCLUDES = -I$(srcdir) -I$(top_srcdir)/libelf -I$(top_srcdir)/libdw \
|
||||
-I$(top_srcdir)/lib -I..
|
||||
-I$(top_srcdir)/lib -I.. -I$(srcdir)/../libasm
|
||||
VERSION = 1
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
LIBEBL_SUBDIR = @LIBEBL_SUBDIR@
|
||||
|
||||
@@ -148,6 +148,11 @@ ssize_t EBLHOOK(register_info) (Ebl *ebl,
|
||||
const char **prefix, const char **setname,
|
||||
int *bits, int *type);
|
||||
|
||||
/* Disassembler function. */
|
||||
int EBLHOOK(disasm) (const uint8_t **startp, const uint8_t *end,
|
||||
GElf_Addr addr, const char *fmt, DisasmOutputCB_t outcb,
|
||||
DisasmGetSymCB_t symcb, void *outcbarg, void *symcbarg);
|
||||
|
||||
|
||||
/* Destructor for ELF backend handle. */
|
||||
void EBLHOOK(destr) (struct ebl *);
|
||||
|
||||
@@ -246,6 +246,7 @@ fill_defaults (Ebl *result)
|
||||
result->bss_plt_p = default_bss_plt_p;
|
||||
result->return_value_location = default_return_value_location;
|
||||
result->register_info = default_register_info;
|
||||
result->disasm = NULL;
|
||||
result->destr = default_destr;
|
||||
result->sysvhash_entrysize = sizeof (Elf32_Word);
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
#define _LIBEBLP_H 1
|
||||
|
||||
#include <gelf.h>
|
||||
#include <libasm.h>
|
||||
#include <libebl.h>
|
||||
#include <libintl.h>
|
||||
|
||||
|
||||
@@ -1,3 +1,14 @@
|
||||
2007-12-20 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* Makefile.am (libelf_a_SOURCES): Add elf_scnshndx.
|
||||
* libelfP.h (struct Elf_Scn): Add shndx_index field.
|
||||
Declare __elf_scnshndx_internal.
|
||||
* elf32_getshdr.c: Record location of extended section header.
|
||||
* elf_begin.c (file_read_elf): Likewise.
|
||||
* elf_scnshndx.c: New file.
|
||||
* libelf.h: Declare elf_scnshndx.
|
||||
* libelf.map: Add elf_scnshndx to version ELFUTILS_1.4.
|
||||
|
||||
2007-11-12 Roland McGrath <roland@redhat.com>
|
||||
|
||||
* libelf.h: Replace off64_t with loff_t throughout.
|
||||
|
||||
+2
-1
@@ -99,7 +99,8 @@ libelf_a_SOURCES = elf_version.c elf_hash.c elf_error.c elf_fill.c \
|
||||
gelf_getlib.c gelf_update_lib.c \
|
||||
elf32_offscn.c elf64_offscn.c gelf_offscn.c \
|
||||
elf_getaroff.c \
|
||||
elf_gnu_hash.c
|
||||
elf_gnu_hash.c \
|
||||
elf_scnshndx.c
|
||||
|
||||
if !MUDFLAP
|
||||
libelf_pic_a_SOURCES =
|
||||
|
||||
@@ -165,6 +165,20 @@ elfw2(LIBELFBITS,getshdr) (scn)
|
||||
CONVERT_TO (shdr[cnt].sh_addralign,
|
||||
notcvt[cnt].sh_addralign);
|
||||
CONVERT_TO (shdr[cnt].sh_entsize, notcvt[cnt].sh_entsize);
|
||||
|
||||
/* If this is a section with an extended index add a
|
||||
reference in the section which uses the extended
|
||||
index. */
|
||||
if (shdr[cnt].sh_type == SHT_SYMTAB_SHNDX
|
||||
&& shdr[cnt].sh_link < shnum)
|
||||
elf->state.ELFW(elf,LIBELFBITS).scns.data[shdr[cnt].sh_link].shndx_index
|
||||
= cnt;
|
||||
|
||||
/* Set the own shndx_index field in case it has not yet
|
||||
been set. */
|
||||
if (elf->state.ELFW(elf,LIBELFBITS).scns.data[cnt].shndx_index == 0)
|
||||
elf->state.ELFW(elf,LIBELFBITS).scns.data[cnt].shndx_index
|
||||
= -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -327,6 +327,19 @@ file_read_elf (int fildes, void *map_address, unsigned char *e_ident,
|
||||
((char *) map_address + offset
|
||||
+ elf->state.elf32.shdr[cnt].sh_offset);
|
||||
elf->state.elf32.scns.data[cnt].list = &elf->state.elf32.scns;
|
||||
|
||||
/* If this is a section with an extended index add a
|
||||
reference in the section which uses the extended
|
||||
index. */
|
||||
if (elf->state.elf32.shdr[cnt].sh_type == SHT_SYMTAB_SHNDX
|
||||
&& elf->state.elf32.shdr[cnt].sh_link < scncnt)
|
||||
elf->state.elf32.scns.data[elf->state.elf32.shdr[cnt].sh_link].shndx_index
|
||||
= cnt;
|
||||
|
||||
/* Set the own shndx_index field in case it has not yet
|
||||
been set. */
|
||||
if (elf->state.elf32.scns.data[cnt].shndx_index == 0)
|
||||
elf->state.elf32.scns.data[cnt].shndx_index = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -402,6 +415,19 @@ file_read_elf (int fildes, void *map_address, unsigned char *e_ident,
|
||||
((char *) map_address + offset
|
||||
+ elf->state.elf64.shdr[cnt].sh_offset);
|
||||
elf->state.elf64.scns.data[cnt].list = &elf->state.elf64.scns;
|
||||
|
||||
/* If this is a section with an extended index add a
|
||||
reference in the section which uses the extended
|
||||
index. */
|
||||
if (elf->state.elf64.shdr[cnt].sh_type == SHT_SYMTAB_SHNDX
|
||||
&& elf->state.elf64.shdr[cnt].sh_link < scncnt)
|
||||
elf->state.elf64.scns.data[elf->state.elf64.shdr[cnt].sh_link].shndx_index
|
||||
= cnt;
|
||||
|
||||
/* Set the own shndx_index field in case it has not yet
|
||||
been set. */
|
||||
if (elf->state.elf64.scns.data[cnt].shndx_index == 0)
|
||||
elf->state.elf64.scns.data[cnt].shndx_index = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/* Get the section index of the extended section index table.
|
||||
Copyright (C) 2007 Red Hat, Inc.
|
||||
This file is part of Red Hat elfutils.
|
||||
Contributed by Ulrich Drepper <drepper@redhat.com>, 2007.
|
||||
|
||||
Red Hat elfutils is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; version 2 of the License.
|
||||
|
||||
Red Hat elfutils is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with Red Hat elfutils; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
|
||||
|
||||
In addition, as a special exception, Red Hat, Inc. gives You the
|
||||
additional right to link the code of Red Hat elfutils with code licensed
|
||||
under any Open Source Initiative certified open source license
|
||||
(http://www.opensource.org/licenses/index.php) which requires the
|
||||
distribution of source code with any binary distribution and to
|
||||
distribute linked combinations of the two. Non-GPL Code permitted under
|
||||
this exception must only link to the code of Red Hat elfutils through
|
||||
those well defined interfaces identified in the file named EXCEPTION
|
||||
found in the source code files (the "Approved Interfaces"). The files
|
||||
of Non-GPL Code may instantiate templates or use macros or inline
|
||||
functions from the Approved Interfaces without causing the resulting
|
||||
work to be covered by the GNU General Public License. Only Red Hat,
|
||||
Inc. may make changes or additions to the list of Approved Interfaces.
|
||||
Red Hat's grant of this exception is conditioned upon your not adding
|
||||
any new exceptions. If you wish to add a new Approved Interface or
|
||||
exception, please contact Red Hat. You must obey the GNU General Public
|
||||
License in all respects for all of the Red Hat elfutils code and other
|
||||
code used in conjunction with Red Hat elfutils except the Non-GPL Code
|
||||
covered by this exception. If you modify this file, you may extend this
|
||||
exception to your version of the file, but you are not obligated to do
|
||||
so. If you do not wish to provide this exception without modification,
|
||||
you must delete this exception statement from your version and license
|
||||
this file solely under the GPL without exception.
|
||||
|
||||
Red Hat elfutils is an included package of the Open Invention Network.
|
||||
An included package of the Open Invention Network is a package for which
|
||||
Open Invention Network licensees cross-license their patents. No patent
|
||||
license is granted, either expressly or impliedly, by designation as an
|
||||
included package. Should you wish to participate in the Open Invention
|
||||
Network licensing program, please visit www.openinventionnetwork.com
|
||||
<http://www.openinventionnetwork.com>. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "libelfP.h"
|
||||
|
||||
|
||||
int
|
||||
elf_scnshndx (Elf_Scn *scn)
|
||||
{
|
||||
if (unlikely (scn->shndx_index == 0))
|
||||
{
|
||||
/* We do not have the value yet. We get it as a side effect of
|
||||
getting a section header. */
|
||||
GElf_Shdr shdr_mem;
|
||||
(void) INTUSE(gelf_getshdr) (scn, &shdr_mem);
|
||||
}
|
||||
|
||||
return scn->shndx_index;
|
||||
}
|
||||
INTDEF(elf_scnshndx)
|
||||
@@ -248,6 +248,10 @@ extern Elf_Scn *elf_nextscn (Elf *__elf, Elf_Scn *__scn);
|
||||
/* Create a new section and append it at the end of the table. */
|
||||
extern Elf_Scn *elf_newscn (Elf *__elf);
|
||||
|
||||
/* Get the section index of the extended section index table for the
|
||||
given symbol table. */
|
||||
extern int elf_scnshndx (Elf_Scn *__scn);
|
||||
|
||||
/* Get the number of sections in the ELF file. If the file uses more
|
||||
sections than can be represented in the e_shnum field of the ELF
|
||||
header the information from the sh_size field in the zeroth section
|
||||
|
||||
+6
-1
@@ -122,4 +122,9 @@ ELFUTILS_1.3 {
|
||||
gelf_getauxv;
|
||||
gelf_update_auxv;
|
||||
gelf_getnote;
|
||||
};
|
||||
} ELFUTILS_1.2;
|
||||
|
||||
ELFUTILS_1.4 {
|
||||
global:
|
||||
elf_scnshndx;
|
||||
} ELFUTILS_1.3;
|
||||
|
||||
+5
-1
@@ -1,5 +1,5 @@
|
||||
/* Internal interfaces for libelf.
|
||||
Copyright (C) 1998,1999,2000,2001,2002,2003,2005,2006,2007 Red Hat, Inc.
|
||||
Copyright (C) 1998-2003, 2005, 2006, 2007 Red Hat, Inc.
|
||||
This file is part of Red Hat elfutils.
|
||||
Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
|
||||
|
||||
@@ -224,6 +224,9 @@ struct Elf_Scn
|
||||
int data_read; /* Nonzero if the section was created by the
|
||||
user or if the data from the file/memory
|
||||
is read. */
|
||||
int shndx_index; /* Index of the extended section index
|
||||
table for this symbol table (if this
|
||||
section is a symbol table). */
|
||||
|
||||
size_t index; /* Index of this section. */
|
||||
struct Elf *elf; /* The underlying ELF file. */
|
||||
@@ -532,6 +535,7 @@ extern Elf_Scn *__elf_getscn_internal (Elf *__elf, size_t __index)
|
||||
attribute_hidden;
|
||||
extern Elf_Scn *__elf_nextscn_internal (Elf *__elf, Elf_Scn *__scn)
|
||||
attribute_hidden;
|
||||
extern int __elf_scnshndx_internal (Elf_Scn *__scn) attribute_hidden;
|
||||
extern Elf_Data *__elf_getdata_internal (Elf_Scn *__scn, Elf_Data *__data)
|
||||
attribute_hidden;
|
||||
extern Elf_Data *__elf_rawdata_internal (Elf_Scn *__scn, Elf_Data *__data)
|
||||
|
||||
@@ -15,6 +15,40 @@
|
||||
* strip.c: Likewise.
|
||||
* unstrip.c: Likewise.
|
||||
|
||||
2007-12-30 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* objdump (show_disasm): Use %e after third parameter.
|
||||
|
||||
2007-12-21 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* strip.c: Fix wrong parenthesis in a few branch predictions.
|
||||
* strings.c: Likewise.
|
||||
|
||||
2007-12-20 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* Makefile.am (DEFS): Add DEBUGPRED.
|
||||
* addr2line.c: Include debugpred.h.
|
||||
* ar.c: Likewise.
|
||||
* elfcmp.c: Likewise.
|
||||
* elflint.c: Likewise.
|
||||
* findtextrel.c: Likewise.
|
||||
* nm.c: Likewise.
|
||||
* objdump.c: Likewise.
|
||||
* ranlib.c: Likewise.
|
||||
* readelf.c: Likewise.
|
||||
* size.c: Likewise.
|
||||
* strings.c: Likewise.
|
||||
* strip.c: Likewise.
|
||||
* unstrip.c: Likewise.
|
||||
* debugpred.h: New file.
|
||||
|
||||
* readelf.c (handle_relocs_rel): Use elf_scnshndx.
|
||||
(handle_relocs_rela): Likewise.
|
||||
|
||||
* readelf.c: Add lots of likely/unlikely.
|
||||
|
||||
* elflint.c: Minor cleanups.
|
||||
|
||||
2007-11-19 Roland McGrath <roland@redhat.com>
|
||||
|
||||
* readelf.c (print_ops): Handle all bad op codes gracefully.
|
||||
|
||||
+7
-4
@@ -24,7 +24,7 @@
|
||||
## Network licensing program, please visit www.openinventionnetwork.com
|
||||
## <http://www.openinventionnetwork.com>.
|
||||
##
|
||||
DEFS = -D_GNU_SOURCE -DHAVE_CONFIG_H $(YYDEBUG) \
|
||||
DEFS = -D_GNU_SOURCE -DHAVE_CONFIG_H $(YYDEBUG) -DDEBUGPRED=@DEBUGPRED@ \
|
||||
-DSRCDIR=\"$(shell cd $(srcdir);pwd)\" -DOBJDIR=\"$(shell pwd)\"
|
||||
if MUDFLAP
|
||||
AM_CFLAGS = -fmudflap
|
||||
@@ -38,7 +38,7 @@ AM_CFLAGS += -Wall -Wshadow -std=gnu99 $(native_ld_cflags) \
|
||||
|
||||
INCLUDES = -I$(srcdir) -I$(srcdir)/../libelf -I$(srcdir)/../libebl \
|
||||
-I$(srcdir)/../libdw -I$(srcdir)/../libdwfl \
|
||||
-I$(srcdir)/../lib -I..
|
||||
-I$(srcdir)/../libasm -I$(srcdir)/../lib -I..
|
||||
|
||||
AM_LDFLAGS = -Wl,-rpath-link,../libelf:../libdw
|
||||
|
||||
@@ -81,7 +81,8 @@ libar_a_SOURCES = arlib.c arlib2.c
|
||||
noinst_HEADERS = ld.h symbolhash.h sectionhash.h versionhash.h \
|
||||
ldscript.h xelf.h unaligned.h
|
||||
|
||||
EXTRA_DIST = elf32-i386.script libld_elf_i386.map $(ld_modules) arlib.h
|
||||
EXTRA_DIST = elf32-i386.script libld_elf_i386.map $(ld_modules) arlib.h \
|
||||
debugpred.h
|
||||
ld_modules = i386_ld.c
|
||||
|
||||
bin_SCRIPTS = make-debug-archive
|
||||
@@ -93,9 +94,11 @@ libmudflap = -lmudflap
|
||||
endif
|
||||
|
||||
if BUILD_STATIC
|
||||
libasm = ../libasm/libasm.a
|
||||
libdw = ../libdw/libdw.a $(libelf) $(libebl) -ldl
|
||||
libelf = ../libelf/libelf.a
|
||||
else
|
||||
libasm = ../libasm/libasm.so
|
||||
libdw = ../libdw/libdw.so
|
||||
libelf = ../libelf/libelf.so
|
||||
endif
|
||||
@@ -122,7 +125,7 @@ elflint_LDADD = $(libebl) $(libelf) $(libeu) $(libmudflap) -ldl
|
||||
findtextrel_LDADD = $(libdw) $(libelf) $(libmudflap)
|
||||
addr2line_LDADD = $(libdw) $(libmudflap)
|
||||
elfcmp_LDADD = $(libebl) $(libelf) $(libmudflap) -ldl
|
||||
objdump_LDADD = $(libebl) $(libelf) $(libeu) $(libmudflap) -ldl
|
||||
objdump_LDADD = $(libasm) $(libebl) $(libelf) $(libeu) $(libmudflap) -ldl
|
||||
ranlib_LDADD = libar.a $(libelf) $(libeu) $(libmudflap)
|
||||
strings_LDADD = $(libelf) $(libeu) $(libmudflap)
|
||||
ar_LDADD = libar.a $(libelf) $(libeu) $(libmudflap)
|
||||
|
||||
@@ -373,3 +373,6 @@ handle_address (GElf_Addr addr, Dwfl *dwfl)
|
||||
else
|
||||
puts ("??:0");
|
||||
}
|
||||
|
||||
|
||||
#include "debugpred.h"
|
||||
|
||||
@@ -1513,3 +1513,6 @@ do_oper_insert (int oper, const char *arfname, char **argv, int argc,
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
#include "debugpred.h"
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/* Support to debug branch prediction.
|
||||
Copyright (C) 2007 Red Hat, Inc.
|
||||
This file is part of Red Hat elfutils.
|
||||
Written by Ulrich Drepper <drepper@redhat.com>, 2007.
|
||||
|
||||
Red Hat elfutils is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; version 2 of the License.
|
||||
|
||||
Red Hat elfutils is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with Red Hat elfutils; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
|
||||
|
||||
Red Hat elfutils is an included package of the Open Invention Network.
|
||||
An included package of the Open Invention Network is a package for which
|
||||
Open Invention Network licensees cross-license their patents. No patent
|
||||
license is granted, either expressly or impliedly, by designation as an
|
||||
included package. Should you wish to participate in the Open Invention
|
||||
Network licensing program, please visit www.openinventionnetwork.com
|
||||
<http://www.openinventionnetwork.com>. */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#if DEBUGPRED
|
||||
extern const unsigned long int __start_predict_data;
|
||||
extern const unsigned long int __stop_predict_data;
|
||||
extern const unsigned long int __start_predict_line;
|
||||
extern const char *__start_predict_file;
|
||||
|
||||
static void
|
||||
__attribute__ ((destructor))
|
||||
predprint (void)
|
||||
{
|
||||
const unsigned long int *s = &__start_predict_data;
|
||||
const unsigned long int *e = &__stop_predict_data;
|
||||
const unsigned long int *sl = &__start_predict_line;
|
||||
const char **sf = &__start_predict_file;
|
||||
while (s < e)
|
||||
{
|
||||
if (s[0] != 0 || s[1] != 0)
|
||||
printf ("%s:%lu: wrong=%lu, correct=%lu%s\n", *sf, *sl, s[0], s[1],
|
||||
s[0] > s[1] ? " <==== WARNING" : "");
|
||||
++sl;
|
||||
++sf;
|
||||
s += 2;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -744,3 +744,6 @@ hash_content_equivalent (size_t entsize, Elf_Data *data1, Elf_Data *data2)
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#include "debugpred.h"
|
||||
|
||||
+7
-5
@@ -579,11 +579,10 @@ check_symtab (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
|
||||
idx, section_name (ebl, idx));
|
||||
|
||||
/* Search for an extended section index table section. */
|
||||
size_t cnt;
|
||||
Elf_Data *xndxdata = NULL;
|
||||
Elf32_Word xndxscnidx = 0;
|
||||
bool found_xndx = false;
|
||||
for (cnt = 1; cnt < shnum; ++cnt)
|
||||
for (size_t cnt = 1; cnt < shnum; ++cnt)
|
||||
if (cnt != (size_t) idx)
|
||||
{
|
||||
Elf_Scn *xndxscn = elf_getscn (ebl->elf, cnt);
|
||||
@@ -608,8 +607,8 @@ section [%2d] '%s': symbol table cannot have more than one extended index sectio
|
||||
|
||||
if (shdr->sh_entsize != gelf_fsize (ebl->elf, ELF_T_SYM, 1, EV_CURRENT))
|
||||
ERROR (gettext ("\
|
||||
section [%2zu] '%s': entry size is does not match ElfXX_Sym\n"),
|
||||
cnt, section_name (ebl, cnt));
|
||||
section [%2u] '%s': entry size is does not match ElfXX_Sym\n"),
|
||||
idx, section_name (ebl, idx));
|
||||
|
||||
/* Test the zeroth entry. */
|
||||
GElf_Sym sym_mem;
|
||||
@@ -644,7 +643,7 @@ section [%2d] '%s': XINDEX for zeroth entry not zero\n"),
|
||||
xndxscnidx, section_name (ebl, xndxscnidx));
|
||||
}
|
||||
|
||||
for (cnt = 1; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
|
||||
for (size_t cnt = 1; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
|
||||
{
|
||||
sym = gelf_getsymshndx (data, xndxdata, cnt, &sym_mem, &xndx);
|
||||
if (sym == NULL)
|
||||
@@ -3958,3 +3957,6 @@ process_elf_file (Elf *elf, const char *prefix, const char *suffix,
|
||||
/* Free the resources. */
|
||||
ebl_closebackend (ebl);
|
||||
}
|
||||
|
||||
|
||||
#include "debugpred.h"
|
||||
|
||||
@@ -606,3 +606,6 @@ a relocation modifies memory at offset %llu in a write-protected segment\n"),
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#include "debugpred.h"
|
||||
|
||||
@@ -1525,3 +1525,6 @@ create_special_section_symbol (struct symbol **symp, const char *name)
|
||||
|
||||
++ld_state.nsymtab;
|
||||
}
|
||||
|
||||
|
||||
#include "debugpred.h"
|
||||
|
||||
@@ -1294,3 +1294,6 @@ handle_elf (Elf *elf, const char *prefix, const char *fname,
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
#include "debugpred.h"
|
||||
|
||||
+83
-5
@@ -681,12 +681,87 @@ show_full_content (Ebl *ebl, const char *fname, uint32_t shstrndx)
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
show_disasm (Ebl *ebl __attribute__ ((unused)),
|
||||
const char *fname __attribute__ ((unused)),
|
||||
uint32_t shstrndx __attribute__ ((unused)))
|
||||
struct disasm_info
|
||||
{
|
||||
/// XXX For now nothing.
|
||||
GElf_Addr addr;
|
||||
const uint8_t *cur;
|
||||
const uint8_t *last_end;
|
||||
};
|
||||
|
||||
|
||||
// XXX This is not the preferred output for all architectures. Needs
|
||||
// XXX customization, too.
|
||||
static int
|
||||
disasm_output (char *buf, size_t buflen, void *arg)
|
||||
{
|
||||
struct disasm_info *info = (struct disasm_info *) arg;
|
||||
|
||||
printf ("%8" PRIx64 ": ", (uint64_t) info->addr);
|
||||
size_t cnt;
|
||||
for (cnt = 0; cnt < (size_t) MIN (info->cur - info->last_end, 8); ++cnt)
|
||||
printf (" %02" PRIx8, info->last_end[cnt]);
|
||||
printf ("%*s %.*s\n",
|
||||
(int) (8 - cnt) * 3 + 1, "", (int) buflen, buf);
|
||||
|
||||
info->addr += cnt;
|
||||
|
||||
/* We limit the number of bytes printed before the mnemonic to 8.
|
||||
Print the rest on a separate, following line. */
|
||||
if (info->cur - info->last_end > 8)
|
||||
{
|
||||
printf ("%8" PRIx64 ": ", (uint64_t) info->addr);
|
||||
for (; cnt < (size_t) (info->cur - info->last_end); ++cnt)
|
||||
printf (" %02" PRIx8, info->last_end[cnt]);
|
||||
putchar_unlocked ('\n');
|
||||
info->addr += info->cur - info->last_end - 8;
|
||||
}
|
||||
|
||||
info->last_end = info->cur;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
show_disasm (Ebl *ebl, const char *fname, uint32_t shstrndx)
|
||||
{
|
||||
DisasmCtx_t *ctx = disasm_begin (ebl, ebl->elf, NULL /* XXX TODO */);
|
||||
if (ctx == NULL)
|
||||
error (EXIT_FAILURE, 0, gettext ("cannot disassemble"));
|
||||
|
||||
Elf_Scn *scn = NULL;
|
||||
while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
|
||||
{
|
||||
GElf_Shdr shdr_mem;
|
||||
GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
|
||||
|
||||
if (shdr == NULL)
|
||||
INTERNAL_ERROR (fname);
|
||||
|
||||
if (shdr->sh_type == SHT_PROGBITS && shdr->sh_size > 0
|
||||
&& (shdr->sh_flags & SHF_EXECINSTR) != 0)
|
||||
{
|
||||
if (! section_match (ebl->elf, elf_ndxscn (scn), shdr, shstrndx))
|
||||
continue;
|
||||
|
||||
Elf_Data *data = elf_getdata (scn, NULL);
|
||||
if (data == NULL)
|
||||
continue;
|
||||
|
||||
printf ("Disassembly of section %s:\n\n",
|
||||
elf_strptr (ebl->elf, shstrndx, shdr->sh_name));
|
||||
|
||||
struct disasm_info info;
|
||||
info.addr = shdr->sh_addr;
|
||||
info.last_end = info.cur = data->d_buf;
|
||||
|
||||
disasm_cb (ctx, &info.cur, info.cur + data->d_size, info.addr,
|
||||
"%7m%e %.1o%e,%.2o%e,%.3o%e", disasm_output, &info,
|
||||
NULL /* XXX */);
|
||||
}
|
||||
}
|
||||
|
||||
(void) disasm_end (ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -735,3 +810,6 @@ handle_elf (Elf *elf, const char *prefix, const char *fname,
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
#include "debugpred.h"
|
||||
|
||||
@@ -304,3 +304,6 @@ handle_file (const char *fname)
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
#include "debugpred.h"
|
||||
|
||||
+121
-135
@@ -535,7 +535,7 @@ process_file (int fd, const char *fname, bool only_one)
|
||||
struct stat64 st;
|
||||
if (fstat64 (fd, &st) != 0)
|
||||
error (0, errno, gettext ("cannot stat input file"));
|
||||
else if (st.st_size == 0)
|
||||
else if (unlikely (st.st_size == 0))
|
||||
error (0, 0, gettext ("input file is empty"));
|
||||
else
|
||||
error (0, 0, gettext ("failed reading '%s': %s"),
|
||||
@@ -575,7 +575,7 @@ process_elf_file (Dwfl_Module *dwflmod, int fd)
|
||||
}
|
||||
|
||||
Ebl *ebl = ebl_openbackend (elf);
|
||||
if (ebl == NULL)
|
||||
if (unlikely (ebl == NULL))
|
||||
{
|
||||
ebl_error:
|
||||
error (0, errno, gettext ("cannot create EBL handle"));
|
||||
@@ -583,7 +583,7 @@ process_elf_file (Dwfl_Module *dwflmod, int fd)
|
||||
}
|
||||
|
||||
/* Determine the number of sections. */
|
||||
if (elf_getshnum (ebl->elf, &shnum) < 0)
|
||||
if (unlikely (elf_getshnum (ebl->elf, &shnum) < 0))
|
||||
error (EXIT_FAILURE, 0,
|
||||
gettext ("cannot determine number of sections: %s"),
|
||||
elf_errmsg (-1));
|
||||
@@ -665,7 +665,7 @@ process_elf_file (Dwfl_Module *dwflmod, int fd)
|
||||
static void
|
||||
print_file_type (unsigned short int e_type)
|
||||
{
|
||||
if (e_type <= ET_CORE)
|
||||
if (likely (e_type <= ET_CORE))
|
||||
{
|
||||
static const char *const knowntypes[] =
|
||||
{
|
||||
@@ -764,7 +764,7 @@ print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr)
|
||||
}
|
||||
fputc_unlocked ('\n', stdout);
|
||||
|
||||
if (ehdr->e_shstrndx == SHN_XINDEX)
|
||||
if (unlikely (ehdr->e_shstrndx == SHN_XINDEX))
|
||||
{
|
||||
GElf_Shdr shdr_mem;
|
||||
GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
|
||||
@@ -820,7 +820,7 @@ There are %d section headers, starting at offset %#" PRIx64 ":\n\
|
||||
ehdr->e_shnum, ehdr->e_shoff);
|
||||
|
||||
/* Get the section header string table index. */
|
||||
if (elf_getshstrndx (ebl->elf, &shstrndx) < 0)
|
||||
if (unlikely (elf_getshstrndx (ebl->elf, &shstrndx) < 0))
|
||||
error (EXIT_FAILURE, 0,
|
||||
gettext ("cannot get section header string table index"));
|
||||
|
||||
@@ -835,14 +835,14 @@ There are %d section headers, starting at offset %#" PRIx64 ":\n\
|
||||
{
|
||||
Elf_Scn *scn = elf_getscn (ebl->elf, cnt);
|
||||
|
||||
if (scn == NULL)
|
||||
if (unlikely (scn == NULL))
|
||||
error (EXIT_FAILURE, 0, gettext ("cannot get section: %s"),
|
||||
elf_errmsg (-1));
|
||||
|
||||
/* Get the section header. */
|
||||
GElf_Shdr shdr_mem;
|
||||
GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
|
||||
if (shdr == NULL)
|
||||
if (unlikely (shdr == NULL))
|
||||
error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"),
|
||||
elf_errmsg (-1));
|
||||
|
||||
@@ -920,7 +920,7 @@ print_phdr (Ebl *ebl, GElf_Ehdr *ehdr)
|
||||
GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
|
||||
|
||||
/* If for some reason the header cannot be returned show this. */
|
||||
if (phdr == NULL)
|
||||
if (unlikely (phdr == NULL))
|
||||
{
|
||||
puts (" ???");
|
||||
continue;
|
||||
@@ -959,7 +959,7 @@ print_phdr (Ebl *ebl, GElf_Ehdr *ehdr)
|
||||
|
||||
/* Get the section header string table index. */
|
||||
size_t shstrndx;
|
||||
if (elf_getshstrndx (ebl->elf, &shstrndx) < 0)
|
||||
if (unlikely (elf_getshstrndx (ebl->elf, &shstrndx) < 0))
|
||||
error (EXIT_FAILURE, 0,
|
||||
gettext ("cannot get section header string table index"));
|
||||
|
||||
@@ -973,7 +973,7 @@ print_phdr (Ebl *ebl, GElf_Ehdr *ehdr)
|
||||
GElf_Phdr phdr_mem;
|
||||
GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &phdr_mem);
|
||||
/* This must not happen. */
|
||||
if (phdr == NULL)
|
||||
if (unlikely (phdr == NULL))
|
||||
error (EXIT_FAILURE, 0, gettext ("cannot get program header: %s"),
|
||||
elf_errmsg (-1));
|
||||
|
||||
@@ -984,14 +984,14 @@ print_phdr (Ebl *ebl, GElf_Ehdr *ehdr)
|
||||
{
|
||||
Elf_Scn *scn = elf_getscn (ebl->elf, inner);
|
||||
/* This should not happen. */
|
||||
if (scn == NULL)
|
||||
if (unlikely (scn == NULL))
|
||||
error (EXIT_FAILURE, 0, gettext ("cannot get section: %s"),
|
||||
elf_errmsg (-1));
|
||||
|
||||
/* Get the section header. */
|
||||
GElf_Shdr shdr_mem;
|
||||
GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
|
||||
if (shdr == NULL)
|
||||
if (unlikely (shdr == NULL))
|
||||
error (EXIT_FAILURE, 0,
|
||||
gettext ("cannot get section header: %s"),
|
||||
elf_errmsg (-1));
|
||||
@@ -1100,7 +1100,7 @@ handle_scngrp (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
|
||||
|
||||
/* Get the section header string table index. */
|
||||
size_t shstrndx;
|
||||
if (elf_getshstrndx (ebl->elf, &shstrndx) < 0)
|
||||
if (unlikely (elf_getshstrndx (ebl->elf, &shstrndx) < 0))
|
||||
error (EXIT_FAILURE, 0,
|
||||
gettext ("cannot get section header string table index"));
|
||||
|
||||
@@ -1282,7 +1282,7 @@ handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
|
||||
return;
|
||||
|
||||
/* Get the section header string table index. */
|
||||
if (elf_getshstrndx (ebl->elf, &shstrndx) < 0)
|
||||
if (unlikely (elf_getshstrndx (ebl->elf, &shstrndx) < 0))
|
||||
error (EXIT_FAILURE, 0,
|
||||
gettext ("cannot get section header string table index"));
|
||||
|
||||
@@ -1431,7 +1431,7 @@ print_relocs (Ebl *ebl)
|
||||
GElf_Shdr shdr_mem;
|
||||
GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
|
||||
|
||||
if (shdr != NULL)
|
||||
if (likely (shdr != NULL))
|
||||
{
|
||||
if (shdr->sh_type == SHT_REL)
|
||||
handle_relocs_rel (ebl, scn, shdr);
|
||||
@@ -1465,7 +1465,7 @@ handle_relocs_rel (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
|
||||
GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
|
||||
&destshdr_mem);
|
||||
|
||||
if (symshdr == NULL || symdata == NULL || destshdr == NULL)
|
||||
if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
|
||||
{
|
||||
printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
|
||||
shdr->sh_offset);
|
||||
@@ -1473,24 +1473,14 @@ handle_relocs_rel (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
|
||||
}
|
||||
|
||||
/* Search for the optional extended section index table. */
|
||||
Elf_Scn *xndxscn = NULL;
|
||||
Elf_Data *xndxdata = NULL;
|
||||
while ((xndxscn = elf_nextscn (ebl->elf, xndxscn)) != NULL)
|
||||
{
|
||||
GElf_Shdr xndxshdr_mem;
|
||||
GElf_Shdr *xndxshdr = gelf_getshdr (xndxscn, &xndxshdr_mem);
|
||||
if (xndxshdr != NULL && xndxshdr->sh_type == SHT_SYMTAB_SHNDX
|
||||
&& xndxshdr->sh_link == elf_ndxscn (symscn))
|
||||
{
|
||||
/* Found it. */
|
||||
xndxdata = elf_getdata (xndxscn, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
int xndxscnidx = elf_scnshndx (scn);
|
||||
if (unlikely (xndxscnidx > 0))
|
||||
xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
|
||||
|
||||
/* Get the section header string table index. */
|
||||
size_t shstrndx;
|
||||
if (elf_getshstrndx (ebl->elf, &shstrndx) < 0)
|
||||
if (unlikely (elf_getshstrndx (ebl->elf, &shstrndx) < 0))
|
||||
error (EXIT_FAILURE, 0,
|
||||
gettext ("cannot get section header string table index"));
|
||||
|
||||
@@ -1530,7 +1520,7 @@ handle_relocs_rel (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
|
||||
{
|
||||
GElf_Rel relmem;
|
||||
GElf_Rel *rel = gelf_getrel (data, cnt, &relmem);
|
||||
if (rel != NULL)
|
||||
if (likely (rel != NULL))
|
||||
{
|
||||
char buf[128];
|
||||
GElf_Sym symmem;
|
||||
@@ -1538,7 +1528,7 @@ handle_relocs_rel (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
|
||||
GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
|
||||
GELF_R_SYM (rel->r_info),
|
||||
&symmem, &xndx);
|
||||
if (sym == NULL)
|
||||
if (unlikely (sym == NULL))
|
||||
printf (" %#0*" PRIx64 " %-20s <%s %ld>\n",
|
||||
class == ELFCLASS32 ? 10 : 18, rel->r_offset,
|
||||
ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
|
||||
@@ -1552,7 +1542,8 @@ handle_relocs_rel (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
|
||||
else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
|
||||
printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n",
|
||||
class == ELFCLASS32 ? 10 : 18, rel->r_offset,
|
||||
ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
|
||||
likely (ebl_reloc_type_check (ebl,
|
||||
GELF_R_TYPE (rel->r_info)))
|
||||
/* Avoid the leading R_ which isn't carrying any
|
||||
information. */
|
||||
? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
|
||||
@@ -1567,7 +1558,7 @@ handle_relocs_rel (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
|
||||
? xndx : sym->st_shndx),
|
||||
&destshdr_mem);
|
||||
|
||||
if (destshdr == NULL)
|
||||
if (unlikely (destshdr == NULL))
|
||||
printf (" %#0*" PRIx64 " %-20s <%s %ld>\n",
|
||||
class == ELFCLASS32 ? 10 : 18, rel->r_offset,
|
||||
ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
|
||||
@@ -1619,7 +1610,7 @@ handle_relocs_rela (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
|
||||
GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
|
||||
&destshdr_mem);
|
||||
|
||||
if (symshdr == NULL || symdata == NULL || destshdr == NULL)
|
||||
if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
|
||||
{
|
||||
printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
|
||||
shdr->sh_offset);
|
||||
@@ -1628,23 +1619,13 @@ handle_relocs_rela (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
|
||||
|
||||
/* Search for the optional extended section index table. */
|
||||
Elf_Data *xndxdata = NULL;
|
||||
Elf_Scn *xndxscn = NULL;
|
||||
while ((xndxscn = elf_nextscn (ebl->elf, xndxscn)) != NULL)
|
||||
{
|
||||
GElf_Shdr xndxshdr_mem;
|
||||
GElf_Shdr *xndxshdr = gelf_getshdr (xndxscn, &xndxshdr_mem);
|
||||
if (xndxshdr != NULL && xndxshdr->sh_type == SHT_SYMTAB_SHNDX
|
||||
&& xndxshdr->sh_link == elf_ndxscn (symscn))
|
||||
{
|
||||
/* Found it. */
|
||||
xndxdata = elf_getdata (xndxscn, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
int xndxscnidx = elf_scnshndx (scn);
|
||||
if (unlikely (xndxscnidx > 0))
|
||||
xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
|
||||
|
||||
/* Get the section header string table index. */
|
||||
size_t shstrndx;
|
||||
if (elf_getshstrndx (ebl->elf, &shstrndx) < 0)
|
||||
if (unlikely (elf_getshstrndx (ebl->elf, &shstrndx) < 0))
|
||||
error (EXIT_FAILURE, 0,
|
||||
gettext ("cannot get section header string table index"));
|
||||
|
||||
@@ -1670,7 +1651,7 @@ handle_relocs_rela (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
|
||||
{
|
||||
GElf_Rela relmem;
|
||||
GElf_Rela *rel = gelf_getrela (data, cnt, &relmem);
|
||||
if (rel != NULL)
|
||||
if (likely (rel != NULL))
|
||||
{
|
||||
char buf[64];
|
||||
GElf_Sym symmem;
|
||||
@@ -1679,7 +1660,7 @@ handle_relocs_rela (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
|
||||
GELF_R_SYM (rel->r_info),
|
||||
&symmem, &xndx);
|
||||
|
||||
if (sym == NULL)
|
||||
if (unlikely (sym == NULL))
|
||||
printf (" %#0*" PRIx64 " %-15s <%s %ld>\n",
|
||||
class == ELFCLASS32 ? 10 : 18, rel->r_offset,
|
||||
ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
|
||||
@@ -1694,7 +1675,8 @@ handle_relocs_rela (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
|
||||
printf ("\
|
||||
%#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n",
|
||||
class == ELFCLASS32 ? 10 : 18, rel->r_offset,
|
||||
ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
|
||||
likely (ebl_reloc_type_check (ebl,
|
||||
GELF_R_TYPE (rel->r_info)))
|
||||
/* Avoid the leading R_ which isn't carrying any
|
||||
information. */
|
||||
? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
|
||||
@@ -1710,7 +1692,7 @@ handle_relocs_rela (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
|
||||
? xndx : sym->st_shndx),
|
||||
&destshdr_mem);
|
||||
|
||||
if (shdr == NULL)
|
||||
if (unlikely (shdr == NULL))
|
||||
printf (" %#0*" PRIx64 " %-15s <%s %ld>\n",
|
||||
class == ELFCLASS32 ? 10 : 18, rel->r_offset,
|
||||
ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
|
||||
@@ -1784,7 +1766,7 @@ handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
|
||||
GElf_Shdr runshdr_mem;
|
||||
GElf_Shdr *runshdr = gelf_getshdr (runscn, &runshdr_mem);
|
||||
|
||||
if (runshdr != NULL)
|
||||
if (likely (runshdr != NULL))
|
||||
{
|
||||
if (runshdr->sh_type == SHT_GNU_versym
|
||||
&& runshdr->sh_link == elf_ndxscn (scn))
|
||||
@@ -1811,7 +1793,7 @@ handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
|
||||
|
||||
/* Get the section header string table index. */
|
||||
size_t shstrndx;
|
||||
if (elf_getshstrndx (ebl->elf, &shstrndx) < 0)
|
||||
if (unlikely (elf_getshstrndx (ebl->elf, &shstrndx) < 0))
|
||||
error (EXIT_FAILURE, 0,
|
||||
gettext ("cannot get section header string table index"));
|
||||
|
||||
@@ -1851,11 +1833,11 @@ handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
|
||||
GElf_Sym sym_mem;
|
||||
GElf_Sym *sym = gelf_getsymshndx (data, xndx_data, cnt, &sym_mem, &xndx);
|
||||
|
||||
if (sym == NULL)
|
||||
if (unlikely (sym == NULL))
|
||||
continue;
|
||||
|
||||
/* Determine the real section index. */
|
||||
if (sym->st_shndx != SHN_XINDEX)
|
||||
if (likely (sym->st_shndx != SHN_XINDEX))
|
||||
xndx = sym->st_shndx;
|
||||
|
||||
printf (gettext ("\
|
||||
@@ -1945,7 +1927,7 @@ handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
|
||||
(unsigned int) vernaux->vna_other);
|
||||
check_def = 0;
|
||||
}
|
||||
else if (! is_nobits)
|
||||
else if (unlikely (! is_nobits))
|
||||
error (0, 0, gettext ("bad dynamic symbol"));
|
||||
else
|
||||
check_def = 1;
|
||||
@@ -2008,7 +1990,7 @@ print_verinfo (Ebl *ebl)
|
||||
GElf_Shdr shdr_mem;
|
||||
GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
|
||||
|
||||
if (shdr != NULL)
|
||||
if (likely (shdr != NULL))
|
||||
{
|
||||
if (shdr->sh_type == SHT_GNU_verneed)
|
||||
handle_verneed (ebl, scn, shdr);
|
||||
@@ -2043,7 +2025,7 @@ get_ver_flags (unsigned int flags)
|
||||
endp = stpcpy (endp, "WEAK ");
|
||||
}
|
||||
|
||||
if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK))
|
||||
if (unlikely (flags & ~(VER_FLG_BASE | VER_FLG_WEAK)))
|
||||
{
|
||||
strncpy (endp, gettext ("| <unknown>"), buf + sizeof (buf) - endp);
|
||||
buf[sizeof (buf) - 1] = '\0';
|
||||
@@ -2065,7 +2047,7 @@ handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
|
||||
|
||||
/* Get the section header string table index. */
|
||||
size_t shstrndx;
|
||||
if (elf_getshstrndx (ebl->elf, &shstrndx) < 0)
|
||||
if (unlikely (elf_getshstrndx (ebl->elf, &shstrndx) < 0))
|
||||
error (EXIT_FAILURE, 0,
|
||||
gettext ("cannot get section header string table index"));
|
||||
|
||||
@@ -2090,7 +2072,7 @@ handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
|
||||
/* Get the data at the next offset. */
|
||||
GElf_Verneed needmem;
|
||||
GElf_Verneed *need = gelf_getverneed (data, offset, &needmem);
|
||||
if (need == NULL)
|
||||
if (unlikely (need == NULL))
|
||||
break;
|
||||
|
||||
printf (gettext (" %#06x: Version: %hu File: %s Cnt: %hu\n"),
|
||||
@@ -2103,7 +2085,7 @@ handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
|
||||
{
|
||||
GElf_Vernaux auxmem;
|
||||
GElf_Vernaux *aux = gelf_getvernaux (data, auxoffset, &auxmem);
|
||||
if (aux == NULL)
|
||||
if (unlikely (aux == NULL))
|
||||
break;
|
||||
|
||||
printf (gettext (" %#06x: Name: %s Flags: %s Version: %hu\n"),
|
||||
@@ -2131,7 +2113,7 @@ handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
|
||||
|
||||
/* Get the section header string table index. */
|
||||
size_t shstrndx;
|
||||
if (elf_getshstrndx (ebl->elf, &shstrndx) < 0)
|
||||
if (unlikely (elf_getshstrndx (ebl->elf, &shstrndx) < 0))
|
||||
error (EXIT_FAILURE, 0,
|
||||
gettext ("cannot get section header string table index"));
|
||||
|
||||
@@ -2158,13 +2140,13 @@ handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
|
||||
/* Get the data at the next offset. */
|
||||
GElf_Verdef defmem;
|
||||
GElf_Verdef *def = gelf_getverdef (data, offset, &defmem);
|
||||
if (def == NULL)
|
||||
if (unlikely (def == NULL))
|
||||
break;
|
||||
|
||||
unsigned int auxoffset = offset + def->vd_aux;
|
||||
GElf_Verdaux auxmem;
|
||||
GElf_Verdaux *aux = gelf_getverdaux (data, auxoffset, &auxmem);
|
||||
if (aux == NULL)
|
||||
if (unlikely (aux == NULL))
|
||||
break;
|
||||
|
||||
printf (gettext ("\
|
||||
@@ -2179,7 +2161,7 @@ handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
|
||||
for (int cnt2 = 1; cnt2 < def->vd_cnt; ++cnt2)
|
||||
{
|
||||
aux = gelf_getverdaux (data, auxoffset, &auxmem);
|
||||
if (aux == NULL)
|
||||
if (unlikely (aux == NULL))
|
||||
break;
|
||||
|
||||
printf (gettext (" %#06x: Parent %d: %s\n"),
|
||||
@@ -2209,7 +2191,7 @@ handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
|
||||
|
||||
/* Get the section header string table index. */
|
||||
size_t shstrndx;
|
||||
if (elf_getshstrndx (ebl->elf, &shstrndx) < 0)
|
||||
if (unlikely (elf_getshstrndx (ebl->elf, &shstrndx) < 0))
|
||||
error (EXIT_FAILURE, 0,
|
||||
gettext ("cannot get section header string table index"));
|
||||
|
||||
@@ -2224,7 +2206,7 @@ handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
|
||||
GElf_Shdr vershdr_mem;
|
||||
GElf_Shdr *vershdr = gelf_getshdr (verscn, &vershdr_mem);
|
||||
|
||||
if (vershdr != NULL)
|
||||
if (likely (vershdr != NULL))
|
||||
{
|
||||
if (vershdr->sh_type == SHT_GNU_verdef)
|
||||
defscn = verscn;
|
||||
@@ -2249,11 +2231,11 @@ handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
|
||||
GElf_Shdr *defshdr;
|
||||
|
||||
defdata = elf_getdata (defscn, NULL);
|
||||
if (defdata == NULL)
|
||||
if (unlikely (defdata == NULL))
|
||||
return;
|
||||
|
||||
defshdr = gelf_getshdr (defscn, &defshdrmem);
|
||||
if (defshdr == NULL)
|
||||
if (unlikely (defshdr == NULL))
|
||||
return;
|
||||
|
||||
for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
|
||||
@@ -2263,7 +2245,7 @@ handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
|
||||
|
||||
/* Get the data at the next offset. */
|
||||
def = gelf_getverdef (defdata, offset, &defmem);
|
||||
if (def == NULL)
|
||||
if (unlikely (def == NULL))
|
||||
break;
|
||||
|
||||
nvername = MAX (nvername, (size_t) (def->vd_ndx & 0x7fff));
|
||||
@@ -2279,11 +2261,11 @@ handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
|
||||
GElf_Shdr *needshdr;
|
||||
|
||||
needdata = elf_getdata (needscn, NULL);
|
||||
if (needdata == NULL)
|
||||
if (unlikely (needdata == NULL))
|
||||
return;
|
||||
|
||||
needshdr = gelf_getshdr (needscn, &needshdrmem);
|
||||
if (needshdr == NULL)
|
||||
if (unlikely (needshdr == NULL))
|
||||
return;
|
||||
|
||||
for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
|
||||
@@ -2295,7 +2277,7 @@ handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
|
||||
|
||||
/* Get the data at the next offset. */
|
||||
need = gelf_getverneed (needdata, offset, &needmem);
|
||||
if (need == NULL)
|
||||
if (unlikely (need == NULL))
|
||||
break;
|
||||
|
||||
/* Run through the auxiliary entries. */
|
||||
@@ -2306,7 +2288,7 @@ handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
|
||||
GElf_Vernaux *aux;
|
||||
|
||||
aux = gelf_getvernaux (needdata, auxoffset, &auxmem);
|
||||
if (aux == NULL)
|
||||
if (unlikely (aux == NULL))
|
||||
break;
|
||||
|
||||
nvername = MAX (nvername,
|
||||
@@ -2337,11 +2319,11 @@ handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
|
||||
GElf_Shdr *defshdr;
|
||||
|
||||
defdata = elf_getdata (defscn, NULL);
|
||||
if (defdata == NULL)
|
||||
if (unlikely (defdata == NULL))
|
||||
return;
|
||||
|
||||
defshdr = gelf_getshdr (defscn, &defshdrmem);
|
||||
if (defshdr == NULL)
|
||||
if (unlikely (defshdr == NULL))
|
||||
return;
|
||||
|
||||
for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
|
||||
@@ -2354,7 +2336,7 @@ handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
|
||||
GElf_Verdaux *aux = gelf_getverdaux (defdata,
|
||||
offset + def->vd_aux,
|
||||
&auxmem);
|
||||
if (def == NULL || aux == NULL)
|
||||
if (unlikely (def == NULL || aux == NULL))
|
||||
break;
|
||||
|
||||
vername[def->vd_ndx & 0x7fff]
|
||||
@@ -2371,7 +2353,7 @@ handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
|
||||
Elf_Data *needdata = elf_getdata (needscn, NULL);
|
||||
GElf_Shdr needshdrmem;
|
||||
GElf_Shdr *needshdr = gelf_getshdr (needscn, &needshdrmem);
|
||||
if (needdata == NULL || needshdr == NULL)
|
||||
if (unlikely (needdata == NULL || needshdr == NULL))
|
||||
return;
|
||||
|
||||
for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
|
||||
@@ -2380,7 +2362,7 @@ handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
|
||||
GElf_Verneed needmem;
|
||||
GElf_Verneed *need = gelf_getverneed (needdata, offset,
|
||||
&needmem);
|
||||
if (need == NULL)
|
||||
if (unlikely (need == NULL))
|
||||
break;
|
||||
|
||||
/* Run through the auxiliary entries. */
|
||||
@@ -2390,7 +2372,7 @@ handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
|
||||
GElf_Vernaux auxmem;
|
||||
GElf_Vernaux *aux = gelf_getvernaux (needdata, auxoffset,
|
||||
&auxmem);
|
||||
if (aux == NULL)
|
||||
if (unlikely (aux == NULL))
|
||||
break;
|
||||
|
||||
vername[aux->vna_other & 0x7fff]
|
||||
@@ -2499,7 +2481,7 @@ print_hash_info (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx,
|
||||
if (extrastr != NULL)
|
||||
fputs (extrastr, stdout);
|
||||
|
||||
if (nbucket > 0)
|
||||
if (likely (nbucket > 0))
|
||||
{
|
||||
uint64_t success = 0;
|
||||
|
||||
@@ -2541,7 +2523,7 @@ static void
|
||||
handle_sysv_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
|
||||
{
|
||||
Elf_Data *data = elf_getdata (scn, NULL);
|
||||
if (data == NULL)
|
||||
if (unlikely (data == NULL))
|
||||
{
|
||||
error (0, 0, gettext ("cannot get data for section %d: %s"),
|
||||
(int) elf_ndxscn (scn), elf_errmsg (-1));
|
||||
@@ -2583,7 +2565,7 @@ static void
|
||||
handle_sysv_hash64 (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
|
||||
{
|
||||
Elf_Data *data = elf_getdata (scn, NULL);
|
||||
if (data == NULL)
|
||||
if (unlikely (data == NULL))
|
||||
{
|
||||
error (0, 0, gettext ("cannot get data for section %d: %s"),
|
||||
(int) elf_ndxscn (scn), elf_errmsg (-1));
|
||||
@@ -2624,7 +2606,7 @@ static void
|
||||
handle_gnu_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
|
||||
{
|
||||
Elf_Data *data = elf_getdata (scn, NULL);
|
||||
if (data == NULL)
|
||||
if (unlikely (data == NULL))
|
||||
{
|
||||
error (0, 0, gettext ("cannot get data for section %d: %s"),
|
||||
(int) elf_ndxscn (scn), elf_errmsg (-1));
|
||||
@@ -2680,13 +2662,15 @@ handle_gnu_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
|
||||
}
|
||||
|
||||
char *str;
|
||||
if (asprintf (&str, gettext ("\
|
||||
if (unlikely (asprintf (&str, gettext ("\
|
||||
Symbol Bias: %u\n\
|
||||
Bitmask Size: %zu bytes %" PRIuFAST32 "%% bits set 2nd hash shift: %u\n"),
|
||||
(unsigned int) symbias, bitmask_words * sizeof (Elf32_Word),
|
||||
((nbits * 100 + 50)
|
||||
/ (uint_fast32_t) (bitmask_words * sizeof (Elf32_Word) * 8)),
|
||||
(unsigned int) shift) == -1)
|
||||
(unsigned int) symbias,
|
||||
bitmask_words * sizeof (Elf32_Word),
|
||||
((nbits * 100 + 50)
|
||||
/ (uint_fast32_t) (bitmask_words
|
||||
* sizeof (Elf32_Word) * 8)),
|
||||
(unsigned int) shift) == -1))
|
||||
error (EXIT_FAILURE, 0, gettext ("memory exhausted"));
|
||||
|
||||
print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
|
||||
@@ -2704,7 +2688,7 @@ handle_hash (Ebl *ebl)
|
||||
{
|
||||
/* Get the section header string table index. */
|
||||
size_t shstrndx;
|
||||
if (elf_getshstrndx (ebl->elf, &shstrndx) < 0)
|
||||
if (unlikely (elf_getshstrndx (ebl->elf, &shstrndx) < 0))
|
||||
error (EXIT_FAILURE, 0,
|
||||
gettext ("cannot get section header string table index"));
|
||||
|
||||
@@ -2715,7 +2699,7 @@ handle_hash (Ebl *ebl)
|
||||
GElf_Shdr shdr_mem;
|
||||
GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
|
||||
|
||||
if (shdr != NULL)
|
||||
if (likely (shdr != NULL))
|
||||
{
|
||||
if (shdr->sh_type == SHT_HASH)
|
||||
{
|
||||
@@ -2740,7 +2724,7 @@ print_liblist (Ebl *ebl)
|
||||
|
||||
/* Get the section header string table index. */
|
||||
size_t shstrndx;
|
||||
if (elf_getshstrndx (ebl->elf, &shstrndx) < 0)
|
||||
if (unlikely (elf_getshstrndx (ebl->elf, &shstrndx) < 0))
|
||||
error (EXIT_FAILURE, 0,
|
||||
gettext ("cannot get section header string table index"));
|
||||
|
||||
@@ -2773,12 +2757,12 @@ print_liblist (Ebl *ebl)
|
||||
{
|
||||
GElf_Lib lib_mem;
|
||||
GElf_Lib *lib = gelf_getlib (data, cnt, &lib_mem);
|
||||
if (lib == NULL)
|
||||
if (unlikely (lib == NULL))
|
||||
continue;
|
||||
|
||||
time_t t = (time_t) lib->l_time_stamp;
|
||||
struct tm *tm = gmtime (&t);
|
||||
if (tm == NULL)
|
||||
if (unlikely (tm == NULL))
|
||||
continue;
|
||||
|
||||
printf (" [%2d] %-29s %04u-%02u-%02uT%02u:%02u:%02u %08x %-7u %u\n",
|
||||
@@ -2936,10 +2920,10 @@ dwarf_tag_string (unsigned int tag)
|
||||
static char buf[40];
|
||||
const char *result = NULL;
|
||||
|
||||
if (tag < nknown_tags)
|
||||
if (likely (tag < nknown_tags))
|
||||
result = known_tags[tag];
|
||||
|
||||
if (result == NULL)
|
||||
if (unlikely (result == NULL))
|
||||
/* There are a few known extensions. */
|
||||
switch (tag)
|
||||
{
|
||||
@@ -3072,10 +3056,10 @@ dwarf_attr_string (unsigned int attrnum)
|
||||
static char buf[40];
|
||||
const char *result = NULL;
|
||||
|
||||
if (attrnum < nknown_attrs)
|
||||
if (likely (attrnum < nknown_attrs))
|
||||
result = known_attrs[attrnum];
|
||||
|
||||
if (result == NULL)
|
||||
if (unlikely (result == NULL))
|
||||
/* There are a few known extensions. */
|
||||
switch (attrnum)
|
||||
{
|
||||
@@ -3218,10 +3202,10 @@ dwarf_form_string (unsigned int form)
|
||||
static char buf[40];
|
||||
const char *result = NULL;
|
||||
|
||||
if (form < nknown_forms)
|
||||
if (likely (form < nknown_forms))
|
||||
result = known_forms[form];
|
||||
|
||||
if (result == NULL)
|
||||
if (unlikely (result == NULL))
|
||||
snprintf (buf, sizeof buf, gettext ("unknown form %" PRIx64),
|
||||
(uint64_t) form);
|
||||
|
||||
@@ -3255,7 +3239,7 @@ dwarf_lang_string (unsigned int lang)
|
||||
[DW_LANG_D] = "D",
|
||||
};
|
||||
|
||||
if (lang < sizeof (known) / sizeof (known[0]))
|
||||
if (likely (lang < sizeof (known) / sizeof (known[0])))
|
||||
return known[lang];
|
||||
else if (lang == DW_LANG_Mips_Assembler)
|
||||
/* This language tag is used for assembler in general. */
|
||||
@@ -3283,7 +3267,7 @@ dwarf_inline_string (unsigned int code)
|
||||
[DW_INL_declared_inlined] = "declared_inlined"
|
||||
};
|
||||
|
||||
if (code < sizeof (known) / sizeof (known[0]))
|
||||
if (likely (code < sizeof (known) / sizeof (known[0])))
|
||||
return known[code];
|
||||
|
||||
return "???";
|
||||
@@ -3313,7 +3297,7 @@ dwarf_encoding_string (unsigned int code)
|
||||
[DW_ATE_decimal_float] = "decimal_float",
|
||||
};
|
||||
|
||||
if (code < sizeof (known) / sizeof (known[0]))
|
||||
if (likely (code < sizeof (known) / sizeof (known[0])))
|
||||
return known[code];
|
||||
|
||||
if (code >= DW_ATE_lo_user && code <= DW_ATE_hi_user)
|
||||
@@ -3337,7 +3321,7 @@ dwarf_access_string (unsigned int code)
|
||||
[DW_ACCESS_private] = "private"
|
||||
};
|
||||
|
||||
if (code < sizeof (known) / sizeof (known[0]))
|
||||
if (likely (code < sizeof (known) / sizeof (known[0])))
|
||||
return known[code];
|
||||
|
||||
return "???";
|
||||
@@ -3354,7 +3338,7 @@ dwarf_visibility_string (unsigned int code)
|
||||
[DW_VIS_qualified] = "qualified"
|
||||
};
|
||||
|
||||
if (code < sizeof (known) / sizeof (known[0]))
|
||||
if (likely (code < sizeof (known) / sizeof (known[0])))
|
||||
return known[code];
|
||||
|
||||
return "???";
|
||||
@@ -3371,7 +3355,7 @@ dwarf_virtuality_string (unsigned int code)
|
||||
[DW_VIRTUALITY_pure_virtual] = "pure_virtual"
|
||||
};
|
||||
|
||||
if (code < sizeof (known) / sizeof (known[0]))
|
||||
if (likely (code < sizeof (known) / sizeof (known[0])))
|
||||
return known[code];
|
||||
|
||||
return "???";
|
||||
@@ -3389,7 +3373,7 @@ dwarf_identifier_case_string (unsigned int code)
|
||||
[DW_ID_case_insensitive] = "insensitive"
|
||||
};
|
||||
|
||||
if (code < sizeof (known) / sizeof (known[0]))
|
||||
if (likely (code < sizeof (known) / sizeof (known[0])))
|
||||
return known[code];
|
||||
|
||||
return "???";
|
||||
@@ -3406,7 +3390,7 @@ dwarf_calling_convention_string (unsigned int code)
|
||||
[DW_CC_nocall] = "nocall",
|
||||
};
|
||||
|
||||
if (code < sizeof (known) / sizeof (known[0]))
|
||||
if (likely (code < sizeof (known) / sizeof (known[0])))
|
||||
return known[code];
|
||||
|
||||
if (code >= DW_CC_lo_user && code <= DW_CC_hi_user)
|
||||
@@ -3429,7 +3413,7 @@ dwarf_ordering_string (unsigned int code)
|
||||
[DW_ORD_col_major] = "col_major"
|
||||
};
|
||||
|
||||
if (code < sizeof (known) / sizeof (known[0]))
|
||||
if (likely (code < sizeof (known) / sizeof (known[0])))
|
||||
return known[code];
|
||||
|
||||
return "???";
|
||||
@@ -3445,7 +3429,7 @@ dwarf_discr_list_string (unsigned int code)
|
||||
[DW_DSC_range] = "range"
|
||||
};
|
||||
|
||||
if (code < sizeof (known) / sizeof (known[0]))
|
||||
if (likely (code < sizeof (known) / sizeof (known[0])))
|
||||
return known[code];
|
||||
|
||||
return "???";
|
||||
@@ -3828,7 +3812,7 @@ print_debug_abbrev_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
|
||||
int res = dwarf_offabbrev (dbg, offset, &length, &abbrev);
|
||||
if (res != 0)
|
||||
{
|
||||
if (res < 0)
|
||||
if (unlikely (res < 0))
|
||||
{
|
||||
printf (gettext ("\
|
||||
*** error while reading abbreviation: %s\n"),
|
||||
@@ -3884,7 +3868,7 @@ print_debug_aranges_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
|
||||
{
|
||||
Dwarf_Aranges *aranges;
|
||||
size_t cnt;
|
||||
if (dwarf_getaranges (dbg, &aranges, &cnt) != 0)
|
||||
if (unlikely (dwarf_getaranges (dbg, &aranges, &cnt) != 0))
|
||||
{
|
||||
error (0, 0, gettext ("cannot get .debug_aranges content: %s"),
|
||||
dwarf_errmsg (-1));
|
||||
@@ -3910,7 +3894,7 @@ print_debug_aranges_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
|
||||
for (size_t n = 0; n < cnt; ++n)
|
||||
{
|
||||
Dwarf_Arange *runp = dwarf_onearange (aranges, n);
|
||||
if (runp == NULL)
|
||||
if (unlikely (runp == NULL))
|
||||
{
|
||||
printf ("cannot get arange %zu: %s\n", n, dwarf_errmsg (-1));
|
||||
return;
|
||||
@@ -3920,7 +3904,7 @@ print_debug_aranges_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
|
||||
Dwarf_Word length;
|
||||
Dwarf_Off offset;
|
||||
|
||||
if (dwarf_getarangeinfo (runp, &start, &length, &offset) != 0)
|
||||
if (unlikely (dwarf_getarangeinfo (runp, &start, &length, &offset) != 0))
|
||||
printf (gettext (" [%*zu] ???\n"), digits, n);
|
||||
else
|
||||
printf (gettext (" [%*zu] start: %0#*" PRIx64
|
||||
@@ -3940,7 +3924,7 @@ print_debug_ranges_section (Dwfl_Module *dwflmod,
|
||||
{
|
||||
Elf_Data *data = elf_rawdata (scn, NULL);
|
||||
|
||||
if (data == NULL)
|
||||
if (unlikely (data == NULL))
|
||||
{
|
||||
error (0, 0, gettext ("cannot get .debug_ranges content: %s"),
|
||||
elf_errmsg (-1));
|
||||
@@ -3959,7 +3943,7 @@ print_debug_ranges_section (Dwfl_Module *dwflmod,
|
||||
{
|
||||
ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
|
||||
|
||||
if (data->d_size - offset < address_size * 2)
|
||||
if (unlikely (data->d_size - offset < address_size * 2))
|
||||
{
|
||||
printf (gettext (" [%6tx] <INVALID DATA>\n"), offset);
|
||||
break;
|
||||
@@ -4291,7 +4275,7 @@ print_debug_info_section (Dwfl_Module *dwflmod,
|
||||
do
|
||||
{
|
||||
offset = dwarf_dieoffset (&dies[level]);
|
||||
if (offset == ~0ul)
|
||||
if (unlikely (offset == ~0ul))
|
||||
{
|
||||
error (0, 0, gettext ("cannot get DIE offset: %s"),
|
||||
dwarf_errmsg (-1));
|
||||
@@ -4299,7 +4283,7 @@ print_debug_info_section (Dwfl_Module *dwflmod,
|
||||
}
|
||||
|
||||
int tag = dwarf_tag (&dies[level]);
|
||||
if (tag == DW_TAG_invalid)
|
||||
if (unlikely (tag == DW_TAG_invalid))
|
||||
{
|
||||
error (0, 0, gettext ("cannot get tag of DIE at offset %" PRIu64
|
||||
" in section '%s': %s"),
|
||||
@@ -4328,7 +4312,7 @@ print_debug_info_section (Dwfl_Module *dwflmod,
|
||||
if (level-- == 0)
|
||||
break;
|
||||
|
||||
if (res == -1)
|
||||
if (unlikely (res == -1))
|
||||
{
|
||||
error (0, 0, gettext ("cannot get next DIE: %s\n"),
|
||||
dwarf_errmsg (-1));
|
||||
@@ -4370,7 +4354,7 @@ print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl,
|
||||
/* There is no functionality in libdw to read the information in the
|
||||
way it is represented here. Hardcode the decoder. */
|
||||
Elf_Data *data = elf_getdata (scn, NULL);
|
||||
if (data == NULL || data->d_buf == NULL)
|
||||
if (unlikely (data == NULL || data->d_buf == NULL))
|
||||
{
|
||||
error (0, 0, gettext ("cannot get line data section data: %s"),
|
||||
elf_errmsg (-1));
|
||||
@@ -4483,7 +4467,7 @@ print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl,
|
||||
while (*linep != 0)
|
||||
{
|
||||
unsigned char *endp = memchr (linep, '\0', lineendp - linep);
|
||||
if (endp == NULL)
|
||||
if (unlikely (endp == NULL))
|
||||
goto invalid_unit;
|
||||
|
||||
printf (" %s\n", (char *) linep);
|
||||
@@ -4502,7 +4486,7 @@ print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl,
|
||||
/* First comes the file name. */
|
||||
char *fname = (char *) linep;
|
||||
unsigned char *endp = memchr (fname, '\0', lineendp - linep);
|
||||
if (endp == NULL)
|
||||
if (unlikely (endp == NULL))
|
||||
goto invalid_unit;
|
||||
linep = endp + 1;
|
||||
|
||||
@@ -4635,7 +4619,7 @@ print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl,
|
||||
char *fname = (char *) linep;
|
||||
unsigned char *endp = memchr (linep, '\0',
|
||||
lineendp - linep);
|
||||
if (endp == NULL)
|
||||
if (unlikely (endp == NULL))
|
||||
goto invalid_unit;
|
||||
linep = endp + 1;
|
||||
|
||||
@@ -4801,7 +4785,7 @@ print_debug_loc_section (Dwfl_Module *dwflmod,
|
||||
{
|
||||
Elf_Data *data = elf_rawdata (scn, NULL);
|
||||
|
||||
if (data == NULL)
|
||||
if (unlikely (data == NULL))
|
||||
{
|
||||
error (0, 0, gettext ("cannot get .debug_loc content: %s"),
|
||||
elf_errmsg (-1));
|
||||
@@ -4820,7 +4804,7 @@ print_debug_loc_section (Dwfl_Module *dwflmod,
|
||||
{
|
||||
ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
|
||||
|
||||
if (data->d_size - offset < address_size * 2)
|
||||
if (unlikely (data->d_size - offset < address_size * 2))
|
||||
{
|
||||
printf (gettext (" [%6tx] <INVALID DATA>\n"), offset);
|
||||
break;
|
||||
@@ -4911,7 +4895,7 @@ print_debug_macinfo_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
|
||||
/* There is no function in libdw to iterate over the raw content of
|
||||
the section but it is easy enough to do. */
|
||||
Elf_Data *data = elf_getdata (scn, NULL);
|
||||
if (data == NULL || data->d_buf == NULL)
|
||||
if (unlikely (data == NULL || data->d_buf == NULL))
|
||||
{
|
||||
error (0, 0, gettext ("cannot get macro information section data: %s"),
|
||||
elf_errmsg (-1));
|
||||
@@ -4990,7 +4974,7 @@ print_debug_macinfo_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
|
||||
get_uleb128 (u128, readp);
|
||||
|
||||
endp = memchr (readp, '\0', readendp - readp);
|
||||
if (endp == NULL)
|
||||
if (unlikely (endp == NULL))
|
||||
{
|
||||
printf (gettext ("\
|
||||
%*s*** non-terminated string at end of section"),
|
||||
@@ -5045,7 +5029,7 @@ print_debug_macinfo_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
|
||||
|
||||
default:
|
||||
// XXX gcc seems to generate files with a trailing zero.
|
||||
if (opcode != 0 || readp != readendp)
|
||||
if (unlikely (opcode != 0 || readp != readendp))
|
||||
printf ("%*s*** invalid opcode %u\n", level, "", opcode);
|
||||
break;
|
||||
}
|
||||
@@ -5112,7 +5096,7 @@ print_debug_str_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
|
||||
{
|
||||
size_t len;
|
||||
const char *str = dwarf_getstring (dbg, offset, &len);
|
||||
if (str == NULL)
|
||||
if (unlikely (str == NULL))
|
||||
{
|
||||
printf (gettext (" *** error while reading strings: %s\n"),
|
||||
dwarf_errmsg (-1));
|
||||
@@ -5140,7 +5124,7 @@ print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr)
|
||||
|
||||
/* Get the section header string table index. */
|
||||
size_t shstrndx;
|
||||
if (elf_getshstrndx (ebl->elf, &shstrndx) < 0)
|
||||
if (unlikely (elf_getshstrndx (ebl->elf, &shstrndx) < 0))
|
||||
error (EXIT_FAILURE, 0,
|
||||
gettext ("cannot get section header string table index"));
|
||||
|
||||
@@ -6052,7 +6036,7 @@ for_each_section_argument (Elf *elf, const struct section_argument *list,
|
||||
{
|
||||
Elf_Scn *scn;
|
||||
GElf_Shdr shdr_mem;
|
||||
const char *name;
|
||||
const char *name = NULL;
|
||||
|
||||
char *endp = NULL;
|
||||
unsigned long int shndx = strtoul (a->arg, &endp, 0);
|
||||
@@ -6085,7 +6069,7 @@ for_each_section_argument (Elf *elf, const struct section_argument *list,
|
||||
break;
|
||||
}
|
||||
|
||||
if (scn == NULL)
|
||||
if (unlikely (scn == NULL))
|
||||
{
|
||||
error (0, 0, gettext ("\nsection '%s' does not exist"), a->arg);
|
||||
continue;
|
||||
@@ -6186,3 +6170,5 @@ dump_archive_index (Elf *elf, const char *fname)
|
||||
printf ("\t%s\n", s->as_name);
|
||||
}
|
||||
}
|
||||
|
||||
#include "debugpred.h"
|
||||
|
||||
@@ -685,3 +685,6 @@ handle_elf (Elf *elf, const char *prefix, const char *fname)
|
||||
show_bsd (elf, prefix, fname, fullname);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#include "debugpred.h"
|
||||
|
||||
+5
-2
@@ -422,13 +422,13 @@ process_chunk (const char *fname, const unsigned char *buf, off64_t to,
|
||||
if (curlen >= min_len)
|
||||
{
|
||||
/* We found a match. */
|
||||
if (unlikely (fname != NULL))
|
||||
if (likely (fname != NULL))
|
||||
{
|
||||
fputs_unlocked (fname, stdout);
|
||||
fputs_unlocked (": ", stdout);
|
||||
}
|
||||
|
||||
if (unlikely (locfmt != NULL))
|
||||
if (likely (locfmt != NULL))
|
||||
printf (locfmt, (int64_t) to - len - (buf - start));
|
||||
|
||||
if (unlikely (*unprinted != NULL))
|
||||
@@ -739,3 +739,6 @@ read_elf (Elf *elf, int fd, const char *fname, off64_t fdlen)
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
#include "debugpred.h"
|
||||
|
||||
+6
-3
@@ -843,7 +843,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
|
||||
if (discard_section)
|
||||
debugshdr.sh_type = SHT_NOBITS;
|
||||
|
||||
if (unlikely (gelf_update_shdr (scn, &debugshdr)) == 0)
|
||||
if (unlikely (gelf_update_shdr (scn, &debugshdr) == 0))
|
||||
/* There cannot be any overflows. */
|
||||
INTERNAL_ERROR (fname);
|
||||
|
||||
@@ -881,7 +881,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
|
||||
debugehdr->e_flags = ehdr->e_flags;
|
||||
debugehdr->e_shstrndx = ehdr->e_shstrndx;
|
||||
|
||||
if (unlikely (gelf_update_ehdr (debugelf, debugehdr)) == 0)
|
||||
if (unlikely (gelf_update_ehdr (debugelf, debugehdr) == 0))
|
||||
{
|
||||
error (0, 0, gettext ("%s: error while creating ELF header: %s"),
|
||||
debug_fname, elf_errmsg (-1));
|
||||
@@ -1547,7 +1547,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
|
||||
};
|
||||
|
||||
/* Finally write the file. */
|
||||
if (unlikely (elf_update (debugelf, ELF_C_WRITE)) == -1)
|
||||
if (unlikely (elf_update (debugelf, ELF_C_WRITE) == -1))
|
||||
{
|
||||
error (0, 0, gettext ("while writing '%s': %s"),
|
||||
debug_fname, elf_errmsg (-1));
|
||||
@@ -1772,3 +1772,6 @@ cannot set access and modification date of '%s'"), fname);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
#include "debugpred.h"
|
||||
|
||||
@@ -2312,3 +2312,6 @@ or - if no debuginfo was found, or . if FILE contains the debug information.\
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#include "debugpred.h"
|
||||
|
||||
@@ -1,3 +1,52 @@
|
||||
2008-01-01 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* testfile44.expect.bz2: New tests.
|
||||
* testfile44.expect.bz2: Adjust.
|
||||
|
||||
2007-12-31 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* testfile44.expect.bz2: New tests.
|
||||
* testfile44.expect.bz2: Adjust.
|
||||
|
||||
2007-12-30 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* testfile44.expect.bz2: New tests.
|
||||
* testfile44.expect.bz2: Adjust.
|
||||
|
||||
2007-12-29 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* testfile44.expect.bz2: New tests.
|
||||
* testfile44.expect.bz2: Adjust.
|
||||
|
||||
2007-12-28 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* testfile44.S.bz2: New tests.
|
||||
* testfile44.expect.bz2: Adjust.
|
||||
|
||||
2007-12-27 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* testfile44.S.bz2: New tests.
|
||||
* testfile44.expect.bz2: Adjust.
|
||||
|
||||
2007-12-26 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* testfile44.S.bz2: New tests.
|
||||
* testfile44.expect.bz2: Adjust
|
||||
|
||||
2007-12-21 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* testfile44.S.bz2: More tests.
|
||||
* testfile44.expect.bz2: Adjust appropriately.
|
||||
|
||||
2007-12-19 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* Makefile.am (TESTS): Add run-disasm.sh.
|
||||
(EXTRA_DIST): Add run-disasm.sh, testfile44.S.bz2, and
|
||||
testfile44.expect.bz2.
|
||||
* run-disasm.sh: New file.
|
||||
* testfile44.S.bz2: New file.
|
||||
* testfile44.expect.bz2: New file.
|
||||
|
||||
2007-12-15 Roland McGrath <roland@redhat.com>
|
||||
|
||||
* run-allregs.sh: Change expected output for powerpc spefscr.
|
||||
|
||||
+4
-2
@@ -83,7 +83,8 @@ TESTS = run-arextract.sh run-arsymtest.sh newfile test-nlist \
|
||||
run-native-test.sh run-bug1-test.sh \
|
||||
dwfl-bug-addr-overflow run-addrname-test.sh \
|
||||
dwfl-bug-fd-leak dwfl-bug-report \
|
||||
run-dwfl-bug-offline-rel.sh run-dwfl-addr-sect.sh
|
||||
run-dwfl-bug-offline-rel.sh run-dwfl-addr-sect.sh \
|
||||
run-disasm.sh
|
||||
# run-show-ciefde.sh
|
||||
|
||||
if !STANDALONE
|
||||
@@ -133,7 +134,8 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh \
|
||||
testfile36.bz2 testfile36.debug.bz2 \
|
||||
testfile37.bz2 testfile37.debug.bz2 \
|
||||
testfile38.bz2 testfile39.bz2 testfile40.bz2 testfile40.debug.bz2 \
|
||||
testfile41.bz2 testfile42.bz2 testfile43.bz2
|
||||
testfile41.bz2 testfile42.bz2 testfile43.bz2 \
|
||||
testfile44.S.bz2 testfile44.expect.bz2 run-disasm.sh
|
||||
|
||||
installed_TESTS_ENVIRONMENT = libdir=$(DESTDIR)$(libdir) \
|
||||
bindir=$(DESTDIR)$(bindir) \
|
||||
|
||||
Executable
+36
@@ -0,0 +1,36 @@
|
||||
#! /bin/sh
|
||||
# Copyright (C) 2007 Red Hat, Inc.
|
||||
# This file is part of Red Hat elfutils.
|
||||
#
|
||||
# Red Hat elfutils is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by the
|
||||
# Free Software Foundation; version 2 of the License.
|
||||
#
|
||||
# Red Hat elfutils is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with Red Hat elfutils; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Red Hat elfutils is an included package of the Open Invention Network.
|
||||
# An included package of the Open Invention Network is a package for which
|
||||
# Open Invention Network licensees cross-license their patents. No patent
|
||||
# license is granted, either expressly or impliedly, by designation as an
|
||||
# included package. Should you wish to participate in the Open Invention
|
||||
# Network licensing program, please visit www.openinventionnetwork.com
|
||||
# <http://www.openinventionnetwork.com>.
|
||||
|
||||
. $srcdir/test-subr.sh
|
||||
|
||||
# Run x86 test.
|
||||
case "$(arch)" in
|
||||
x86_64 | i?86 )
|
||||
tempfiles testfile44.o
|
||||
testfiles testfile44.S testfile44.expect
|
||||
gcc -m32 -c -o testfile44.o testfile44.S
|
||||
testrun_compare ../src/objdump -d testfile44.o < testfile44.expect
|
||||
;;
|
||||
esac
|
||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user