Compare commits
19 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
27c75a9a90 | ||
|
d0cd3b8d84 | ||
|
9af9eaaa76 | ||
|
8c8f42f76c | ||
|
51fe68905b | ||
|
7fe70ecc56 | ||
|
d03cda5923 | ||
|
30ac07d4f0 | ||
|
8857052055 | ||
|
ce11fedc6e | ||
|
43d4145a98 | ||
|
295defa5f1 | ||
|
f801f97e04 | ||
|
f48c3dd51a | ||
|
62296fe351 | ||
|
32f36bcefc | ||
|
bc8a22cc30 | ||
|
f631ef9bd2 | ||
|
f7341ff400 |
42
Changelog
42
Changelog
@@ -1,8 +1,50 @@
|
||||
version 0.1.5:
|
||||
|
||||
- ppc64 support + personality() patch (Rusty Russell)
|
||||
- first Alpha CPU patches (Falk Hueffner)
|
||||
- removed bfd.h dependancy
|
||||
- fixed shrd, shld, idivl and divl on PowerPC.
|
||||
- fixed buggy glibc PowerPC rint() function (test-i386 passes now on PowerPC).
|
||||
|
||||
version 0.1.4:
|
||||
|
||||
- more accurate VM86 emulation (can launch small DOS 16 bit
|
||||
executables in wine).
|
||||
- fixed push/pop fs/gs
|
||||
- added iret instruction.
|
||||
- added times() syscall and SIOCATMARK ioctl.
|
||||
|
||||
version 0.1.3:
|
||||
|
||||
- S390 support (Ulrich Weigand)
|
||||
- glibc 2.3.x compile fix (Ulrich Weigand)
|
||||
- socketcall endian fix (Ulrich Weigand)
|
||||
- struct sockaddr endian fix (Ulrich Weigand)
|
||||
- sendmsg/recvmsg endian fix (Ulrich Weigand)
|
||||
- execve endian fix (Ulrich Weigand)
|
||||
- fdset endian fix (Ulrich Weigand)
|
||||
- partial setsockopt syscall support (Ulrich Weigand)
|
||||
- more accurate pushf/popf emulation
|
||||
- first partial vm86() syscall support (can be used with runcom example).
|
||||
- added bound, cmpxchg8b, cpuid instructions
|
||||
- added 16 bit addressing support/override for string operations
|
||||
- poll() fix
|
||||
|
||||
version 0.1.2:
|
||||
|
||||
- compile fixes
|
||||
- xlat instruction
|
||||
- xchg instruction memory lock
|
||||
- added simple vm86 example (not working with QEMU yet). The 54 byte
|
||||
DOS executable 'pi_10.com' program was released by Bertram
|
||||
Felgenhauer (more information at http://www.boo.net/~jasonp/pipage.html).
|
||||
|
||||
version 0.1.1:
|
||||
|
||||
- glibc 2.2 compilation fixes
|
||||
- added -s and -L options
|
||||
- binary distribution of x86 glibc and wine
|
||||
- big endian fixes in ELF loader and getdents.
|
||||
|
||||
version 0.1:
|
||||
|
||||
|
13
Makefile
13
Makefile
@@ -13,14 +13,20 @@ OP_CFLAGS+= -falign-functions=0
|
||||
else
|
||||
OP_CFLAGS+= -malign-functions=0
|
||||
endif
|
||||
# WARNING: this LDFLAGS is _very_ tricky : qemu is an ELF shared object
|
||||
# that the kernel ELF loader considers as an executable. I think this
|
||||
# is the simplest way to make it self virtualizable!
|
||||
LDFLAGS+=-Wl,-shared
|
||||
endif
|
||||
|
||||
ifeq ($(ARCH),ppc)
|
||||
OP_CFLAGS=$(CFLAGS)
|
||||
LDFLAGS+=-Wl,-T,ppc.ld
|
||||
endif
|
||||
|
||||
ifeq ($(ARCH),s390)
|
||||
OP_CFLAGS=$(CFLAGS)
|
||||
LDFLAGS+=-Wl,-T,s390.ld
|
||||
endif
|
||||
|
||||
ifeq ($(GCC_MAJOR),3)
|
||||
@@ -31,7 +37,6 @@ endif
|
||||
#########################################################
|
||||
|
||||
DEFINES+=-D_GNU_SOURCE
|
||||
LDSCRIPT=$(ARCH).ld
|
||||
LIBS+=-lm
|
||||
|
||||
# profiling code
|
||||
@@ -51,7 +56,7 @@ LIBOBJS+=i386-dis.o dis-buf.o
|
||||
all: qemu qemu-doc.html
|
||||
|
||||
qemu: $(OBJS)
|
||||
$(CC) -Wl,-T,$(LDSCRIPT) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||
|
||||
depend: $(SRCS)
|
||||
$(CC) -MM $(CFLAGS) $^ 1>.depend
|
||||
@@ -103,9 +108,9 @@ dyngen.c ioctls.h ops_template.h op_string.h syscall_types.h\
|
||||
Makefile elf.h linux_bin.h segment.h thunk.c\
|
||||
elfload.c main.c signal.c thunk.h\
|
||||
cpu-i386.h qemu.h op-i386.c opc-i386.h syscall-i386.h translate-i386.c\
|
||||
dis-asm.h gen-i386.h op-i386.h syscall.c\
|
||||
dis-asm.h gen-i386.h syscall.c\
|
||||
dis-buf.c i386-dis.c opreg_template.h syscall_defs.h\
|
||||
i386.ld ppc.ld s390.ld exec-i386.h exec-i386.c configure \
|
||||
ppc.ld s390.ld exec-i386.h exec-i386.c configure \
|
||||
tests/Makefile\
|
||||
tests/test-i386.c tests/test-i386-shift.h tests/test-i386.h\
|
||||
tests/test-i386-muldiv.h tests/test-i386-code16.S\
|
||||
|
7
TODO
7
TODO
@@ -1,10 +1,11 @@
|
||||
- fix thread locks
|
||||
- optimize translated cache chaining (DLL PLT-like system)
|
||||
- fix thread stack liberation (use kernel 2.5.xxx CLONE_CHILD_CLEARTID)
|
||||
- fix x86 stack allocation
|
||||
- fix iret/lret restarting
|
||||
- more syscalls (in particular all 64 bit ones, IPCs, fix 64 bit
|
||||
issues, fix 16 bit uid issues)
|
||||
- finish signal handing (fp87 state, more siginfo conversions)
|
||||
- verify thread support (clone() and various locks)
|
||||
- vm86 syscall support
|
||||
- overrides/16bit for string ops
|
||||
- make it self runnable (use same trick as ld.so : include its own relocator and libc)
|
||||
- improved 16 bit support
|
||||
- fix FPU exceptions (in particular: gen_op_fpush not before mem load)
|
||||
|
10
configure
vendored
10
configure
vendored
@@ -36,7 +36,7 @@ case "$cpu" in
|
||||
alpha)
|
||||
cpu="alpha"
|
||||
;;
|
||||
"Power Macintosh"|ppc)
|
||||
"Power Macintosh"|ppc|ppc64)
|
||||
cpu="powerpc"
|
||||
;;
|
||||
mips)
|
||||
@@ -209,14 +209,22 @@ echo "CFLAGS=$CFLAGS" >> config.mak
|
||||
echo "LDFLAGS=$LDFLAGS" >> config.mak
|
||||
if test "$cpu" = "x86" ; then
|
||||
echo "ARCH=i386" >> config.mak
|
||||
echo "#define HOST_I386 1" >> $TMPH
|
||||
elif test "$cpu" = "armv4l" ; then
|
||||
echo "ARCH=arm" >> config.mak
|
||||
echo "#define HOST_ARM 1" >> $TMPH
|
||||
elif test "$cpu" = "powerpc" ; then
|
||||
echo "ARCH=ppc" >> config.mak
|
||||
echo "#define HOST_PPC 1" >> $TMPH
|
||||
elif test "$cpu" = "mips" ; then
|
||||
echo "ARCH=mips" >> config.mak
|
||||
echo "#define HOST_MIPS 1" >> $TMPH
|
||||
elif test "$cpu" = "s390" ; then
|
||||
echo "ARCH=s390" >> config.mak
|
||||
echo "#define HOST_S390 1" >> $TMPH
|
||||
elif test "$cpu" = "alpha" ; then
|
||||
echo "ARCH=alpha" >> config.mak
|
||||
echo "#define HOST_ALPHA 1" >> $TMPH
|
||||
else
|
||||
echo "Unsupported CPU"
|
||||
exit 1
|
||||
|
36
cpu-i386.h
36
cpu-i386.h
@@ -68,24 +68,24 @@
|
||||
#define VIP_MASK 0x00100000
|
||||
#define ID_MASK 0x00200000
|
||||
|
||||
#define EXCP00_DIVZ 1
|
||||
#define EXCP01_SSTP 2
|
||||
#define EXCP02_NMI 3
|
||||
#define EXCP03_INT3 4
|
||||
#define EXCP04_INTO 5
|
||||
#define EXCP05_BOUND 6
|
||||
#define EXCP06_ILLOP 7
|
||||
#define EXCP07_PREX 8
|
||||
#define EXCP08_DBLE 9
|
||||
#define EXCP09_XERR 10
|
||||
#define EXCP0A_TSS 11
|
||||
#define EXCP0B_NOSEG 12
|
||||
#define EXCP0C_STACK 13
|
||||
#define EXCP0D_GPF 14
|
||||
#define EXCP0E_PAGE 15
|
||||
#define EXCP10_COPR 17
|
||||
#define EXCP11_ALGN 18
|
||||
#define EXCP12_MCHK 19
|
||||
#define EXCP00_DIVZ 0
|
||||
#define EXCP01_SSTP 1
|
||||
#define EXCP02_NMI 2
|
||||
#define EXCP03_INT3 3
|
||||
#define EXCP04_INTO 4
|
||||
#define EXCP05_BOUND 5
|
||||
#define EXCP06_ILLOP 6
|
||||
#define EXCP07_PREX 7
|
||||
#define EXCP08_DBLE 8
|
||||
#define EXCP09_XERR 9
|
||||
#define EXCP0A_TSS 10
|
||||
#define EXCP0B_NOSEG 11
|
||||
#define EXCP0C_STACK 12
|
||||
#define EXCP0D_GPF 13
|
||||
#define EXCP0E_PAGE 14
|
||||
#define EXCP10_COPR 16
|
||||
#define EXCP11_ALGN 17
|
||||
#define EXCP12_MCHK 18
|
||||
|
||||
#define EXCP_INTERRUPT 256 /* async interruption */
|
||||
|
||||
|
149
dis-asm.h
149
dis-asm.h
@@ -11,7 +11,152 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "bfd.h"
|
||||
#include <inttypes.h>
|
||||
|
||||
#define PARAMS(x) x
|
||||
typedef void *PTR;
|
||||
typedef uint64_t bfd_vma;
|
||||
typedef uint8_t bfd_byte;
|
||||
|
||||
enum bfd_flavour {
|
||||
bfd_target_unknown_flavour,
|
||||
bfd_target_aout_flavour,
|
||||
bfd_target_coff_flavour,
|
||||
bfd_target_ecoff_flavour,
|
||||
bfd_target_elf_flavour,
|
||||
bfd_target_ieee_flavour,
|
||||
bfd_target_nlm_flavour,
|
||||
bfd_target_oasys_flavour,
|
||||
bfd_target_tekhex_flavour,
|
||||
bfd_target_srec_flavour,
|
||||
bfd_target_ihex_flavour,
|
||||
bfd_target_som_flavour,
|
||||
bfd_target_os9k_flavour,
|
||||
bfd_target_versados_flavour,
|
||||
bfd_target_msdos_flavour,
|
||||
bfd_target_evax_flavour
|
||||
};
|
||||
|
||||
enum bfd_endian { BFD_ENDIAN_BIG, BFD_ENDIAN_LITTLE, BFD_ENDIAN_UNKNOWN };
|
||||
|
||||
enum bfd_architecture
|
||||
{
|
||||
bfd_arch_unknown, /* File arch not known */
|
||||
bfd_arch_obscure, /* Arch known, not one of these */
|
||||
bfd_arch_m68k, /* Motorola 68xxx */
|
||||
#define bfd_mach_m68000 1
|
||||
#define bfd_mach_m68008 2
|
||||
#define bfd_mach_m68010 3
|
||||
#define bfd_mach_m68020 4
|
||||
#define bfd_mach_m68030 5
|
||||
#define bfd_mach_m68040 6
|
||||
#define bfd_mach_m68060 7
|
||||
bfd_arch_vax, /* DEC Vax */
|
||||
bfd_arch_i960, /* Intel 960 */
|
||||
/* The order of the following is important.
|
||||
lower number indicates a machine type that
|
||||
only accepts a subset of the instructions
|
||||
available to machines with higher numbers.
|
||||
The exception is the "ca", which is
|
||||
incompatible with all other machines except
|
||||
"core". */
|
||||
|
||||
#define bfd_mach_i960_core 1
|
||||
#define bfd_mach_i960_ka_sa 2
|
||||
#define bfd_mach_i960_kb_sb 3
|
||||
#define bfd_mach_i960_mc 4
|
||||
#define bfd_mach_i960_xa 5
|
||||
#define bfd_mach_i960_ca 6
|
||||
#define bfd_mach_i960_jx 7
|
||||
#define bfd_mach_i960_hx 8
|
||||
|
||||
bfd_arch_a29k, /* AMD 29000 */
|
||||
bfd_arch_sparc, /* SPARC */
|
||||
#define bfd_mach_sparc 1
|
||||
/* The difference between v8plus and v9 is that v9 is a true 64 bit env. */
|
||||
#define bfd_mach_sparc_sparclet 2
|
||||
#define bfd_mach_sparc_sparclite 3
|
||||
#define bfd_mach_sparc_v8plus 4
|
||||
#define bfd_mach_sparc_v8plusa 5 /* with ultrasparc add'ns */
|
||||
#define bfd_mach_sparc_v9 6
|
||||
#define bfd_mach_sparc_v9a 7 /* with ultrasparc add'ns */
|
||||
/* Nonzero if MACH has the v9 instruction set. */
|
||||
#define bfd_mach_sparc_v9_p(mach) \
|
||||
((mach) >= bfd_mach_sparc_v8plus && (mach) <= bfd_mach_sparc_v9a)
|
||||
bfd_arch_mips, /* MIPS Rxxxx */
|
||||
#define bfd_mach_mips3000 3000
|
||||
#define bfd_mach_mips3900 3900
|
||||
#define bfd_mach_mips4000 4000
|
||||
#define bfd_mach_mips4010 4010
|
||||
#define bfd_mach_mips4100 4100
|
||||
#define bfd_mach_mips4300 4300
|
||||
#define bfd_mach_mips4400 4400
|
||||
#define bfd_mach_mips4600 4600
|
||||
#define bfd_mach_mips4650 4650
|
||||
#define bfd_mach_mips5000 5000
|
||||
#define bfd_mach_mips6000 6000
|
||||
#define bfd_mach_mips8000 8000
|
||||
#define bfd_mach_mips10000 10000
|
||||
#define bfd_mach_mips16 16
|
||||
bfd_arch_i386, /* Intel 386 */
|
||||
#define bfd_mach_i386_i386 0
|
||||
#define bfd_mach_i386_i8086 1
|
||||
bfd_arch_we32k, /* AT&T WE32xxx */
|
||||
bfd_arch_tahoe, /* CCI/Harris Tahoe */
|
||||
bfd_arch_i860, /* Intel 860 */
|
||||
bfd_arch_romp, /* IBM ROMP PC/RT */
|
||||
bfd_arch_alliant, /* Alliant */
|
||||
bfd_arch_convex, /* Convex */
|
||||
bfd_arch_m88k, /* Motorola 88xxx */
|
||||
bfd_arch_pyramid, /* Pyramid Technology */
|
||||
bfd_arch_h8300, /* Hitachi H8/300 */
|
||||
#define bfd_mach_h8300 1
|
||||
#define bfd_mach_h8300h 2
|
||||
#define bfd_mach_h8300s 3
|
||||
bfd_arch_powerpc, /* PowerPC */
|
||||
bfd_arch_rs6000, /* IBM RS/6000 */
|
||||
bfd_arch_hppa, /* HP PA RISC */
|
||||
bfd_arch_d10v, /* Mitsubishi D10V */
|
||||
bfd_arch_z8k, /* Zilog Z8000 */
|
||||
#define bfd_mach_z8001 1
|
||||
#define bfd_mach_z8002 2
|
||||
bfd_arch_h8500, /* Hitachi H8/500 */
|
||||
bfd_arch_sh, /* Hitachi SH */
|
||||
#define bfd_mach_sh 0
|
||||
#define bfd_mach_sh3 0x30
|
||||
#define bfd_mach_sh3e 0x3e
|
||||
#define bfd_mach_sh4 0x40
|
||||
bfd_arch_alpha, /* Dec Alpha */
|
||||
bfd_arch_arm, /* Advanced Risc Machines ARM */
|
||||
#define bfd_mach_arm_2 1
|
||||
#define bfd_mach_arm_2a 2
|
||||
#define bfd_mach_arm_3 3
|
||||
#define bfd_mach_arm_3M 4
|
||||
#define bfd_mach_arm_4 5
|
||||
#define bfd_mach_arm_4T 6
|
||||
bfd_arch_ns32k, /* National Semiconductors ns32000 */
|
||||
bfd_arch_w65, /* WDC 65816 */
|
||||
bfd_arch_tic30, /* Texas Instruments TMS320C30 */
|
||||
bfd_arch_v850, /* NEC V850 */
|
||||
#define bfd_mach_v850 0
|
||||
bfd_arch_arc, /* Argonaut RISC Core */
|
||||
#define bfd_mach_arc_base 0
|
||||
bfd_arch_m32r, /* Mitsubishi M32R/D */
|
||||
#define bfd_mach_m32r 0 /* backwards compatibility */
|
||||
bfd_arch_mn10200, /* Matsushita MN10200 */
|
||||
bfd_arch_mn10300, /* Matsushita MN10300 */
|
||||
bfd_arch_last
|
||||
};
|
||||
|
||||
typedef struct symbol_cache_entry
|
||||
{
|
||||
const char *name;
|
||||
union
|
||||
{
|
||||
PTR p;
|
||||
bfd_vma i;
|
||||
} udata;
|
||||
} asymbol;
|
||||
|
||||
typedef int (*fprintf_ftype) PARAMS((FILE*, const char*, ...));
|
||||
|
||||
@@ -176,8 +321,10 @@ extern int print_insn_d10v PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_v850 PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_tic30 PARAMS ((bfd_vma, disassemble_info*));
|
||||
|
||||
#if 0
|
||||
/* Fetch the disassembler for a given BFD, if that support is available. */
|
||||
extern disassembler_ftype disassembler PARAMS ((bfd *));
|
||||
#endif
|
||||
|
||||
|
||||
/* This block of definitions is for particular callers who read instructions
|
||||
|
243
dyngen.c
243
dyngen.c
@@ -22,25 +22,62 @@
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <inttypes.h>
|
||||
#include <elf.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "thunk.h"
|
||||
#include "config.h"
|
||||
|
||||
/* temporary fix to make it compile with old elf headers (XXX: use
|
||||
included elf.h in all cases) */
|
||||
#ifndef EM_390
|
||||
#define EM_S390 22 /* IBM S390 */
|
||||
#define R_390_8 1 /* Direct 8 bit. */
|
||||
#define R_390_16 3 /* Direct 16 bit. */
|
||||
#define R_390_32 4 /* Direct 32 bit. */
|
||||
/* elf format definitions. We use these macros to test the CPU to
|
||||
allow cross compilation (this tool must be ran on the build
|
||||
platform) */
|
||||
#if defined(HOST_I386)
|
||||
|
||||
#define ELF_CLASS ELFCLASS32
|
||||
#define ELF_ARCH EM_386
|
||||
#define elf_check_arch(x) ( ((x) == EM_386) || ((x) == EM_486) )
|
||||
#undef ELF_USES_RELOCA
|
||||
|
||||
#elif defined(HOST_PPC)
|
||||
|
||||
#define ELF_CLASS ELFCLASS32
|
||||
#define ELF_ARCH EM_PPC
|
||||
#define elf_check_arch(x) ((x) == EM_PPC)
|
||||
#define ELF_USES_RELOCA
|
||||
|
||||
#elif defined(HOST_S390)
|
||||
|
||||
#define ELF_CLASS ELFCLASS32
|
||||
#define ELF_ARCH EM_S390
|
||||
#define elf_check_arch(x) ((x) == EM_S390)
|
||||
#define ELF_USES_RELOCA
|
||||
|
||||
#elif defined(HOST_ALPHA)
|
||||
|
||||
#define ELF_CLASS ELFCLASS64
|
||||
#define ELF_ARCH EM_ALPHA
|
||||
#define elf_check_arch(x) ((x) == EM_ALPHA)
|
||||
#define ELF_USES_RELOCA
|
||||
|
||||
#else
|
||||
#error unsupported CPU - please update the code
|
||||
#endif
|
||||
|
||||
#if ELF_CLASS == ELFCLASS32
|
||||
typedef int32_t host_long;
|
||||
typedef uint32_t host_ulong;
|
||||
#else
|
||||
typedef int64_t host_long;
|
||||
typedef uint64_t host_ulong;
|
||||
#endif
|
||||
|
||||
#include "elf.h"
|
||||
|
||||
#include "thunk.h"
|
||||
|
||||
/* all dynamically generated functions begin with this code */
|
||||
#define OP_PREFIX "op_"
|
||||
|
||||
int elf_must_swap(Elf32_Ehdr *h)
|
||||
int elf_must_swap(struct elfhdr *h)
|
||||
{
|
||||
union {
|
||||
uint32_t i;
|
||||
@@ -62,19 +99,25 @@ void swab32s(uint32_t *p)
|
||||
*p = bswap32(*p);
|
||||
}
|
||||
|
||||
void swab64s(uint32_t *p)
|
||||
void swab64s(uint64_t *p)
|
||||
{
|
||||
*p = bswap64(*p);
|
||||
}
|
||||
|
||||
void elf_swap_ehdr(Elf32_Ehdr *h)
|
||||
#if ELF_CLASS == ELFCLASS32
|
||||
#define swabls(x) swab32s(x)
|
||||
#else
|
||||
#define swabls(x) swab64s(x)
|
||||
#endif
|
||||
|
||||
void elf_swap_ehdr(struct elfhdr *h)
|
||||
{
|
||||
swab16s(&h->e_type); /* Object file type */
|
||||
swab16s(&h-> e_machine); /* Architecture */
|
||||
swab32s(&h-> e_version); /* Object file version */
|
||||
swab32s(&h-> e_entry); /* Entry point virtual address */
|
||||
swab32s(&h-> e_phoff); /* Program header table file offset */
|
||||
swab32s(&h-> e_shoff); /* Section header table file offset */
|
||||
swabls(&h-> e_entry); /* Entry point virtual address */
|
||||
swabls(&h-> e_phoff); /* Program header table file offset */
|
||||
swabls(&h-> e_shoff); /* Section header table file offset */
|
||||
swab32s(&h-> e_flags); /* Processor-specific flags */
|
||||
swab16s(&h-> e_ehsize); /* ELF header size in bytes */
|
||||
swab16s(&h-> e_phentsize); /* Program header table entry size */
|
||||
@@ -84,34 +127,33 @@ void elf_swap_ehdr(Elf32_Ehdr *h)
|
||||
swab16s(&h-> e_shstrndx); /* Section header string table index */
|
||||
}
|
||||
|
||||
void elf_swap_shdr(Elf32_Shdr *h)
|
||||
void elf_swap_shdr(struct elf_shdr *h)
|
||||
{
|
||||
swab32s(&h-> sh_name); /* Section name (string tbl index) */
|
||||
swab32s(&h-> sh_type); /* Section type */
|
||||
swab32s(&h-> sh_flags); /* Section flags */
|
||||
swab32s(&h-> sh_addr); /* Section virtual addr at execution */
|
||||
swab32s(&h-> sh_offset); /* Section file offset */
|
||||
swab32s(&h-> sh_size); /* Section size in bytes */
|
||||
swabls(&h-> sh_flags); /* Section flags */
|
||||
swabls(&h-> sh_addr); /* Section virtual addr at execution */
|
||||
swabls(&h-> sh_offset); /* Section file offset */
|
||||
swabls(&h-> sh_size); /* Section size in bytes */
|
||||
swab32s(&h-> sh_link); /* Link to another section */
|
||||
swab32s(&h-> sh_info); /* Additional section information */
|
||||
swab32s(&h-> sh_addralign); /* Section alignment */
|
||||
swab32s(&h-> sh_entsize); /* Entry size if section holds table */
|
||||
swabls(&h-> sh_addralign); /* Section alignment */
|
||||
swabls(&h-> sh_entsize); /* Entry size if section holds table */
|
||||
}
|
||||
|
||||
void elf_swap_phdr(Elf32_Phdr *h)
|
||||
void elf_swap_phdr(struct elf_phdr *h)
|
||||
{
|
||||
swab32s(&h->p_type); /* Segment type */
|
||||
swab32s(&h->p_offset); /* Segment file offset */
|
||||
swab32s(&h->p_vaddr); /* Segment virtual address */
|
||||
swab32s(&h->p_paddr); /* Segment physical address */
|
||||
swab32s(&h->p_filesz); /* Segment size in file */
|
||||
swab32s(&h->p_memsz); /* Segment size in memory */
|
||||
swabls(&h->p_offset); /* Segment file offset */
|
||||
swabls(&h->p_vaddr); /* Segment virtual address */
|
||||
swabls(&h->p_paddr); /* Segment physical address */
|
||||
swabls(&h->p_filesz); /* Segment size in file */
|
||||
swabls(&h->p_memsz); /* Segment size in memory */
|
||||
swab32s(&h->p_flags); /* Segment flags */
|
||||
swab32s(&h->p_align); /* Segment alignment */
|
||||
swabls(&h->p_align); /* Segment alignment */
|
||||
}
|
||||
|
||||
int do_swap;
|
||||
int e_machine;
|
||||
|
||||
uint16_t get16(uint16_t *p)
|
||||
{
|
||||
@@ -157,12 +199,12 @@ void __attribute__((noreturn)) error(const char *fmt, ...)
|
||||
}
|
||||
|
||||
|
||||
Elf32_Shdr *find_elf_section(Elf32_Shdr *shdr, int shnum, const char *shstr,
|
||||
struct elf_shdr *find_elf_section(struct elf_shdr *shdr, int shnum, const char *shstr,
|
||||
const char *name)
|
||||
{
|
||||
int i;
|
||||
const char *shname;
|
||||
Elf32_Shdr *sec;
|
||||
struct elf_shdr *sec;
|
||||
|
||||
for(i = 0; i < shnum; i++) {
|
||||
sec = &shdr[i];
|
||||
@@ -209,20 +251,21 @@ int strstart(const char *str, const char *val, const char **ptr)
|
||||
#define MAX_ARGS 3
|
||||
|
||||
/* generate op code */
|
||||
void gen_code(const char *name, unsigned long offset, unsigned long size,
|
||||
FILE *outfile, uint8_t *text, void *relocs, int nb_relocs, int reloc_sh_type,
|
||||
Elf32_Sym *symtab, char *strtab, int gen_switch)
|
||||
void gen_code(const char *name, host_ulong offset, host_ulong size,
|
||||
FILE *outfile, uint8_t *text, ELF_RELOC *relocs, int nb_relocs, int reloc_sh_type,
|
||||
ElfW(Sym) *symtab, char *strtab, int gen_switch)
|
||||
{
|
||||
int copy_size = 0;
|
||||
uint8_t *p_start, *p_end;
|
||||
int nb_args, i;
|
||||
int nb_args, i, n;
|
||||
uint8_t args_present[MAX_ARGS];
|
||||
const char *sym_name, *p;
|
||||
ELF_RELOC *rel;
|
||||
|
||||
/* compute exact size excluding return instruction */
|
||||
p_start = text + offset;
|
||||
p_end = p_start + size;
|
||||
switch(e_machine) {
|
||||
switch(ELF_ARCH) {
|
||||
case EM_386:
|
||||
{
|
||||
uint8_t *p;
|
||||
@@ -256,20 +299,15 @@ void gen_code(const char *name, unsigned long offset, unsigned long size,
|
||||
copy_size = p - p_start;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
error("unsupported CPU (%d)", e_machine);
|
||||
}
|
||||
|
||||
/* compute the number of arguments by looking at the relocations */
|
||||
for(i = 0;i < MAX_ARGS; i++)
|
||||
args_present[i] = 0;
|
||||
|
||||
if (reloc_sh_type == SHT_REL) {
|
||||
Elf32_Rel *rel;
|
||||
int n;
|
||||
for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
|
||||
if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) {
|
||||
sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name;
|
||||
sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
|
||||
if (strstart(sym_name, "__op_param", &p)) {
|
||||
n = strtoul(p, NULL, 10);
|
||||
if (n >= MAX_ARGS)
|
||||
@@ -278,21 +316,6 @@ void gen_code(const char *name, unsigned long offset, unsigned long size,
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Elf32_Rela *rel;
|
||||
int n;
|
||||
for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
|
||||
if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) {
|
||||
sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name;
|
||||
if (strstart(sym_name, "__op_param", &p)) {
|
||||
n = strtoul(p, NULL, 10);
|
||||
if (n >= MAX_ARGS)
|
||||
error("too many arguments in %s", name);
|
||||
args_present[n - 1] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nb_args = 0;
|
||||
while (nb_args < MAX_ARGS && args_present[nb_args])
|
||||
@@ -319,8 +342,6 @@ void gen_code(const char *name, unsigned long offset, unsigned long size,
|
||||
}
|
||||
fprintf(outfile, " extern void %s();\n", name);
|
||||
|
||||
if (reloc_sh_type == SHT_REL) {
|
||||
Elf32_Rel *rel;
|
||||
for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
|
||||
if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) {
|
||||
sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name;
|
||||
@@ -329,17 +350,6 @@ void gen_code(const char *name, unsigned long offset, unsigned long size,
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Elf32_Rela *rel;
|
||||
for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
|
||||
if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) {
|
||||
sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name;
|
||||
if (!strstart(sym_name, "__op_param", &p)) {
|
||||
fprintf(outfile, "extern char %s;\n", sym_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(outfile, " memcpy(gen_code_ptr, &%s, %d);\n", name, copy_size);
|
||||
for(i = 0; i < nb_args; i++) {
|
||||
@@ -347,13 +357,11 @@ void gen_code(const char *name, unsigned long offset, unsigned long size,
|
||||
}
|
||||
|
||||
/* patch relocations */
|
||||
switch(e_machine) {
|
||||
case EM_386:
|
||||
#if defined(HOST_I386)
|
||||
{
|
||||
Elf32_Rel *rel;
|
||||
char name[256];
|
||||
int type;
|
||||
long addend;
|
||||
int addend;
|
||||
for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
|
||||
if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) {
|
||||
sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name;
|
||||
@@ -366,11 +374,11 @@ void gen_code(const char *name, unsigned long offset, unsigned long size,
|
||||
addend = get32((uint32_t *)(text + rel->r_offset));
|
||||
switch(type) {
|
||||
case R_386_32:
|
||||
fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %ld) = %s + %ld;\n",
|
||||
fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
|
||||
rel->r_offset - offset, name, addend);
|
||||
break;
|
||||
case R_386_PC32:
|
||||
fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %ld) = %s - (long)(gen_code_ptr + %ld) + %ld;\n",
|
||||
fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %d) + %d;\n",
|
||||
rel->r_offset - offset, name, rel->r_offset - offset, addend);
|
||||
break;
|
||||
default:
|
||||
@@ -379,13 +387,11 @@ void gen_code(const char *name, unsigned long offset, unsigned long size,
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EM_PPC:
|
||||
#elif defined(HOST_PPC)
|
||||
{
|
||||
Elf32_Rela *rel;
|
||||
char name[256];
|
||||
int type;
|
||||
long addend;
|
||||
int addend;
|
||||
for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
|
||||
if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) {
|
||||
sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name;
|
||||
@@ -398,24 +404,24 @@ void gen_code(const char *name, unsigned long offset, unsigned long size,
|
||||
addend = rel->r_addend;
|
||||
switch(type) {
|
||||
case R_PPC_ADDR32:
|
||||
fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %ld) = %s + %ld;\n",
|
||||
fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
|
||||
rel->r_offset - offset, name, addend);
|
||||
break;
|
||||
case R_PPC_ADDR16_LO:
|
||||
fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %ld) = (%s + %ld);\n",
|
||||
fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d) = (%s + %d);\n",
|
||||
rel->r_offset - offset, name, addend);
|
||||
break;
|
||||
case R_PPC_ADDR16_HI:
|
||||
fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %ld) = (%s + %ld) >> 16;\n",
|
||||
fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d) = (%s + %d) >> 16;\n",
|
||||
rel->r_offset - offset, name, addend);
|
||||
break;
|
||||
case R_PPC_ADDR16_HA:
|
||||
fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %ld) = (%s + %ld + 0x8000) >> 16;\n",
|
||||
fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d) = (%s + %d + 0x8000) >> 16;\n",
|
||||
rel->r_offset - offset, name, addend);
|
||||
break;
|
||||
case R_PPC_REL24:
|
||||
/* warning: must be at 32 MB distancy */
|
||||
fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %ld) = (*(uint32_t *)(gen_code_ptr + %ld) & ~0x03fffffc) | ((%s - (long)(gen_code_ptr + %ld) + %ld) & 0x03fffffc);\n",
|
||||
fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = (*(uint32_t *)(gen_code_ptr + %d) & ~0x03fffffc) | ((%s - (long)(gen_code_ptr + %d) + %d) & 0x03fffffc);\n",
|
||||
rel->r_offset - offset, rel->r_offset - offset, name, rel->r_offset - offset, addend);
|
||||
break;
|
||||
default:
|
||||
@@ -424,13 +430,11 @@ void gen_code(const char *name, unsigned long offset, unsigned long size,
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EM_S390:
|
||||
#elif defined(HOST_S390)
|
||||
{
|
||||
Elf32_Rela *rel;
|
||||
char name[256];
|
||||
int type;
|
||||
long addend;
|
||||
int addend;
|
||||
for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
|
||||
if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) {
|
||||
sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name;
|
||||
@@ -443,15 +447,15 @@ void gen_code(const char *name, unsigned long offset, unsigned long size,
|
||||
addend = rel->r_addend;
|
||||
switch(type) {
|
||||
case R_390_32:
|
||||
fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %ld) = %s + %ld;\n",
|
||||
fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
|
||||
rel->r_offset - offset, name, addend);
|
||||
break;
|
||||
case R_390_16:
|
||||
fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %ld) = %s + %ld;\n",
|
||||
fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d) = %s + %d;\n",
|
||||
rel->r_offset - offset, name, addend);
|
||||
break;
|
||||
case R_390_8:
|
||||
fprintf(outfile, " *(uint8_t *)(gen_code_ptr + %ld) = %s + %ld;\n",
|
||||
fprintf(outfile, " *(uint8_t *)(gen_code_ptr + %d) = %s + %d;\n",
|
||||
rel->r_offset - offset, name, addend);
|
||||
break;
|
||||
default:
|
||||
@@ -460,10 +464,9 @@ void gen_code(const char *name, unsigned long offset, unsigned long size,
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
error("unsupported CPU for relocations (%d)", e_machine);
|
||||
}
|
||||
#else
|
||||
#error unsupported CPU
|
||||
#endif
|
||||
fprintf(outfile, " gen_code_ptr += %d;\n", copy_size);
|
||||
fprintf(outfile, "}\n");
|
||||
fprintf(outfile, "break;\n\n");
|
||||
@@ -492,11 +495,10 @@ void gen_code(const char *name, unsigned long offset, unsigned long size,
|
||||
int load_elf(const char *filename, FILE *outfile, int do_print_enum)
|
||||
{
|
||||
int fd;
|
||||
Elf32_Ehdr ehdr;
|
||||
Elf32_Shdr *sec, *shdr, *symtab_sec, *strtab_sec, *text_sec;
|
||||
struct elfhdr ehdr;
|
||||
struct elf_shdr *sec, *shdr, *symtab_sec, *strtab_sec, *text_sec;
|
||||
int i, j, nb_syms;
|
||||
Elf32_Sym *symtab, *sym;
|
||||
const char *cpu_name;
|
||||
ElfW(Sym) *symtab, *sym;
|
||||
char *shstr, *strtab;
|
||||
uint8_t *text;
|
||||
void *relocs;
|
||||
@@ -515,7 +517,6 @@ int load_elf(const char *filename, FILE *outfile, int do_print_enum)
|
||||
|| ehdr.e_ident[EI_MAG1] != ELFMAG1
|
||||
|| ehdr.e_ident[EI_MAG2] != ELFMAG2
|
||||
|| ehdr.e_ident[EI_MAG3] != ELFMAG3
|
||||
|| ehdr.e_ident[EI_CLASS] != ELFCLASS32
|
||||
|| ehdr.e_ident[EI_VERSION] != EV_CURRENT) {
|
||||
error("bad ELF header");
|
||||
}
|
||||
@@ -523,14 +524,17 @@ int load_elf(const char *filename, FILE *outfile, int do_print_enum)
|
||||
do_swap = elf_must_swap(&ehdr);
|
||||
if (do_swap)
|
||||
elf_swap_ehdr(&ehdr);
|
||||
if (ehdr.e_ident[EI_CLASS] != ELF_CLASS)
|
||||
error("Unsupported ELF class");
|
||||
if (ehdr.e_type != ET_REL)
|
||||
error("ELF object file expected");
|
||||
if (ehdr.e_version != EV_CURRENT)
|
||||
error("Invalid ELF version");
|
||||
e_machine = ehdr.e_machine;
|
||||
if (!elf_check_arch(ehdr.e_machine))
|
||||
error("Unsupported CPU (e_machine=%d)", ehdr.e_machine);
|
||||
|
||||
/* read section headers */
|
||||
shdr = load_data(fd, ehdr.e_shoff, ehdr.e_shnum * sizeof(Elf32_Shdr));
|
||||
shdr = load_data(fd, ehdr.e_shoff, ehdr.e_shnum * sizeof(struct elf_shdr));
|
||||
if (do_swap) {
|
||||
for(i = 0; i < ehdr.e_shnum; i++) {
|
||||
elf_swap_shdr(&shdr[i]);
|
||||
@@ -590,35 +594,12 @@ int load_elf(const char *filename, FILE *outfile, int do_print_enum)
|
||||
if (do_swap) {
|
||||
for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
|
||||
swab32s(&sym->st_name);
|
||||
swab32s(&sym->st_value);
|
||||
swab32s(&sym->st_size);
|
||||
swabls(&sym->st_value);
|
||||
swabls(&sym->st_size);
|
||||
swab16s(&sym->st_shndx);
|
||||
}
|
||||
}
|
||||
|
||||
switch(e_machine) {
|
||||
case EM_386:
|
||||
cpu_name = "i386";
|
||||
break;
|
||||
case EM_PPC:
|
||||
cpu_name = "ppc";
|
||||
break;
|
||||
case EM_MIPS:
|
||||
cpu_name = "mips";
|
||||
break;
|
||||
case EM_ARM:
|
||||
cpu_name = "arm";
|
||||
break;
|
||||
case EM_SPARC:
|
||||
cpu_name = "sparc";
|
||||
break;
|
||||
case EM_S390:
|
||||
cpu_name = "s390";
|
||||
break;
|
||||
default:
|
||||
error("unsupported CPU (e_machine=%d)", e_machine);
|
||||
}
|
||||
|
||||
if (do_print_enum) {
|
||||
fprintf(outfile, "DEF(end, 0)\n");
|
||||
for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
|
||||
@@ -669,7 +650,7 @@ fprintf(outfile,
|
||||
);
|
||||
|
||||
/* generate a return */
|
||||
switch(e_machine) {
|
||||
switch(ELF_ARCH) {
|
||||
case EM_386:
|
||||
fprintf(outfile, "*gen_code_ptr++ = 0xc3; /* ret */\n");
|
||||
break;
|
||||
@@ -679,8 +660,6 @@ fprintf(outfile,
|
||||
case EM_S390:
|
||||
fprintf(outfile, "*((uint16_t *)gen_code_ptr)++ = 0x07fe; /* br %%r14 */\n");
|
||||
break;
|
||||
default:
|
||||
error("no return generation for cpu '%s'", cpu_name);
|
||||
}
|
||||
|
||||
fprintf(outfile, "return gen_code_ptr - gen_code_buf;\n");
|
||||
|
803
elf.h
803
elf.h
@@ -1,47 +1,25 @@
|
||||
/*
|
||||
* ELF register definitions..
|
||||
*/
|
||||
#ifndef _ELF_H
|
||||
#define _ELF_H
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
typedef uint32_t elf_greg_t;
|
||||
|
||||
#define ELF_NGREG (sizeof (struct target_pt_regs) / sizeof(elf_greg_t))
|
||||
typedef elf_greg_t elf_gregset_t[ELF_NGREG];
|
||||
|
||||
typedef struct user_i387_struct elf_fpregset_t;
|
||||
|
||||
/*
|
||||
* This is used to ensure we don't load something for the wrong architecture.
|
||||
*/
|
||||
#define elf_check_arch(x) ( ((x) == EM_386) || ((x) == EM_486) )
|
||||
|
||||
/*
|
||||
* These are used to set parameters in the core dumps.
|
||||
*/
|
||||
#define ELF_CLASS ELFCLASS32
|
||||
#define ELF_DATA ELFDATA2LSB;
|
||||
#define ELF_ARCH EM_386
|
||||
|
||||
/* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program
|
||||
starts %edx contains a pointer to a function which might be
|
||||
registered using `atexit'. This provides a mean for the
|
||||
dynamic linker to call DT_FINI functions for shared libraries
|
||||
that have been loaded before the code runs.
|
||||
|
||||
A value of 0 tells we have no such handler. */
|
||||
#define ELF_PLAT_INIT(_r) _r->edx = 0
|
||||
|
||||
#define USE_ELF_CORE_DUMP
|
||||
#define ELF_EXEC_PAGESIZE 4096
|
||||
|
||||
|
||||
/* 32-bit ELF base types. */
|
||||
typedef uint32_t Elf32_Addr;
|
||||
typedef uint16_t Elf32_Half;
|
||||
typedef uint32_t Elf32_Off;
|
||||
typedef int32_t Elf32_Sword;
|
||||
typedef uint32_t Elf32_Word;
|
||||
|
||||
/* 64-bit ELF base types. */
|
||||
typedef uint64_t Elf64_Addr;
|
||||
typedef uint16_t Elf64_Half;
|
||||
typedef int16_t Elf64_SHalf;
|
||||
typedef uint64_t Elf64_Off;
|
||||
typedef int32_t Elf64_Sword;
|
||||
typedef uint32_t Elf64_Word;
|
||||
typedef uint64_t Elf64_Xword;
|
||||
typedef int64_t Elf64_Sxword;
|
||||
|
||||
/* These constants are for the segment types stored in the image headers */
|
||||
#define PT_NULL 0
|
||||
#define PT_LOAD 1
|
||||
@@ -52,6 +30,13 @@ typedef uint32_t Elf32_Word;
|
||||
#define PT_PHDR 6
|
||||
#define PT_LOPROC 0x70000000
|
||||
#define PT_HIPROC 0x7fffffff
|
||||
#define PT_MIPS_REGINFO 0x70000000
|
||||
|
||||
/* Flags in the e_flags field of the header */
|
||||
#define EF_MIPS_NOREORDER 0x00000001
|
||||
#define EF_MIPS_PIC 0x00000002
|
||||
#define EF_MIPS_CPIC 0x00000004
|
||||
#define EF_MIPS_ARCH 0xf0000000
|
||||
|
||||
/* These constants define the different elf file types */
|
||||
#define ET_NONE 0
|
||||
@@ -59,8 +44,8 @@ typedef uint32_t Elf32_Word;
|
||||
#define ET_EXEC 2
|
||||
#define ET_DYN 3
|
||||
#define ET_CORE 4
|
||||
#define ET_LOPROC 5
|
||||
#define ET_HIPROC 6
|
||||
#define ET_LOPROC 0xff00
|
||||
#define ET_HIPROC 0xffff
|
||||
|
||||
/* These constants define the various ELF target machines */
|
||||
#define EM_NONE 0
|
||||
@@ -76,13 +61,31 @@ typedef uint32_t Elf32_Word;
|
||||
|
||||
#define EM_MIPS_RS4_BE 10 /* MIPS R4000 big-endian */
|
||||
|
||||
#define EM_SPARC64 11 /* SPARC v9 (not official) 64-bit */
|
||||
|
||||
#define EM_PARISC 15 /* HPPA */
|
||||
|
||||
#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */
|
||||
|
||||
#define EM_PPC 20 /* PowerPC */
|
||||
#define EM_PPC64 21 /* PowerPC64 */
|
||||
|
||||
#define EM_ARM 40 /* ARM */
|
||||
|
||||
#define EM_SH 42 /* SuperH */
|
||||
|
||||
#define EM_SPARCV9 43 /* SPARC v9 64-bit */
|
||||
|
||||
#define EM_IA_64 50 /* HP/Intel IA-64 */
|
||||
|
||||
#define EM_X86_64 62 /* AMD x86-64 */
|
||||
|
||||
#define EM_S390 22 /* IBM S/390 */
|
||||
|
||||
#define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */
|
||||
|
||||
#define EM_V850 87 /* NEC v850 */
|
||||
|
||||
#define EM_H8_300H 47 /* Hitachi H8/300H */
|
||||
#define EM_H8S 48 /* Hitachi H8S */
|
||||
|
||||
/*
|
||||
* This is an interim value that we will use until the committee comes
|
||||
@@ -90,6 +93,13 @@ typedef uint32_t Elf32_Word;
|
||||
*/
|
||||
#define EM_ALPHA 0x9026
|
||||
|
||||
/* Bogus old v850 magic number, used by old tools. */
|
||||
#define EM_CYGNUS_V850 0x9080
|
||||
|
||||
/*
|
||||
* This is the old interim value for S/390 architecture
|
||||
*/
|
||||
#define EM_S390_OLD 0xA390
|
||||
|
||||
/* This is the info that is needed to parse the dynamic section of the file */
|
||||
#define DT_NULL 0
|
||||
@@ -118,6 +128,25 @@ typedef uint32_t Elf32_Word;
|
||||
#define DT_JMPREL 23
|
||||
#define DT_LOPROC 0x70000000
|
||||
#define DT_HIPROC 0x7fffffff
|
||||
#define DT_MIPS_RLD_VERSION 0x70000001
|
||||
#define DT_MIPS_TIME_STAMP 0x70000002
|
||||
#define DT_MIPS_ICHECKSUM 0x70000003
|
||||
#define DT_MIPS_IVERSION 0x70000004
|
||||
#define DT_MIPS_FLAGS 0x70000005
|
||||
#define RHF_NONE 0
|
||||
#define RHF_HARDWAY 1
|
||||
#define RHF_NOTPOT 2
|
||||
#define DT_MIPS_BASE_ADDRESS 0x70000006
|
||||
#define DT_MIPS_CONFLICT 0x70000008
|
||||
#define DT_MIPS_LIBLIST 0x70000009
|
||||
#define DT_MIPS_LOCAL_GOTNO 0x7000000a
|
||||
#define DT_MIPS_CONFLICTNO 0x7000000b
|
||||
#define DT_MIPS_LIBLISTNO 0x70000010
|
||||
#define DT_MIPS_SYMTABNO 0x70000011
|
||||
#define DT_MIPS_UNREFEXTNO 0x70000012
|
||||
#define DT_MIPS_GOTSYM 0x70000013
|
||||
#define DT_MIPS_HIPAGENO 0x70000014
|
||||
#define DT_MIPS_RLD_MAP 0x70000016
|
||||
|
||||
/* This info is needed when parsing the symbol table */
|
||||
#define STB_LOCAL 0
|
||||
@@ -130,8 +159,12 @@ typedef uint32_t Elf32_Word;
|
||||
#define STT_SECTION 3
|
||||
#define STT_FILE 4
|
||||
|
||||
#define ELF32_ST_BIND(x) ((x) >> 4)
|
||||
#define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf)
|
||||
#define ELF_ST_BIND(x) ((x) >> 4)
|
||||
#define ELF_ST_TYPE(x) (((unsigned int) x) & 0xf)
|
||||
#define ELF32_ST_BIND(x) ELF_ST_BIND(x)
|
||||
#define ELF32_ST_TYPE(x) ELF_ST_TYPE(x)
|
||||
#define ELF64_ST_BIND(x) ELF_ST_BIND(x)
|
||||
#define ELF64_ST_TYPE(x) ELF_ST_TYPE(x)
|
||||
|
||||
/* Symbolic values for the entries in the auxiliary table
|
||||
put on the initial stack */
|
||||
@@ -150,7 +183,9 @@ typedef uint32_t Elf32_Word;
|
||||
#define AT_EUID 12 /* effective uid */
|
||||
#define AT_GID 13 /* real gid */
|
||||
#define AT_EGID 14 /* effective gid */
|
||||
|
||||
#define AT_PLATFORM 15 /* string identifying CPU for optimizations */
|
||||
#define AT_HWCAP 16 /* arch dependent hints at CPU capabilities */
|
||||
#define AT_CLKTCK 17 /* frequency at which times() increments */
|
||||
|
||||
typedef struct dynamic{
|
||||
Elf32_Sword d_tag;
|
||||
@@ -161,10 +196,10 @@ typedef struct dynamic{
|
||||
} Elf32_Dyn;
|
||||
|
||||
typedef struct {
|
||||
unsigned long long d_tag; /* entry tag value */
|
||||
Elf64_Sxword d_tag; /* entry tag value */
|
||||
union {
|
||||
unsigned long long d_val;
|
||||
unsigned long long d_ptr;
|
||||
Elf64_Xword d_val;
|
||||
Elf64_Addr d_ptr;
|
||||
} d_un;
|
||||
} Elf64_Dyn;
|
||||
|
||||
@@ -172,6 +207,9 @@ typedef struct {
|
||||
#define ELF32_R_SYM(x) ((x) >> 8)
|
||||
#define ELF32_R_TYPE(x) ((x) & 0xff)
|
||||
|
||||
#define ELF64_R_SYM(i) ((i) >> 32)
|
||||
#define ELF64_R_TYPE(i) ((i) & 0xffffffff)
|
||||
|
||||
#define R_386_NONE 0
|
||||
#define R_386_32 1
|
||||
#define R_386_PC32 2
|
||||
@@ -185,14 +223,559 @@ typedef struct {
|
||||
#define R_386_GOTPC 10
|
||||
#define R_386_NUM 11
|
||||
|
||||
#define R_MIPS_NONE 0
|
||||
#define R_MIPS_16 1
|
||||
#define R_MIPS_32 2
|
||||
#define R_MIPS_REL32 3
|
||||
#define R_MIPS_26 4
|
||||
#define R_MIPS_HI16 5
|
||||
#define R_MIPS_LO16 6
|
||||
#define R_MIPS_GPREL16 7
|
||||
#define R_MIPS_LITERAL 8
|
||||
#define R_MIPS_GOT16 9
|
||||
#define R_MIPS_PC16 10
|
||||
#define R_MIPS_CALL16 11
|
||||
#define R_MIPS_GPREL32 12
|
||||
/* The remaining relocs are defined on Irix, although they are not
|
||||
in the MIPS ELF ABI. */
|
||||
#define R_MIPS_UNUSED1 13
|
||||
#define R_MIPS_UNUSED2 14
|
||||
#define R_MIPS_UNUSED3 15
|
||||
#define R_MIPS_SHIFT5 16
|
||||
#define R_MIPS_SHIFT6 17
|
||||
#define R_MIPS_64 18
|
||||
#define R_MIPS_GOT_DISP 19
|
||||
#define R_MIPS_GOT_PAGE 20
|
||||
#define R_MIPS_GOT_OFST 21
|
||||
/*
|
||||
* The following two relocation types are specified in the MIPS ABI
|
||||
* conformance guide version 1.2 but not yet in the psABI.
|
||||
*/
|
||||
#define R_MIPS_GOTHI16 22
|
||||
#define R_MIPS_GOTLO16 23
|
||||
#define R_MIPS_SUB 24
|
||||
#define R_MIPS_INSERT_A 25
|
||||
#define R_MIPS_INSERT_B 26
|
||||
#define R_MIPS_DELETE 27
|
||||
#define R_MIPS_HIGHER 28
|
||||
#define R_MIPS_HIGHEST 29
|
||||
/*
|
||||
* The following two relocation types are specified in the MIPS ABI
|
||||
* conformance guide version 1.2 but not yet in the psABI.
|
||||
*/
|
||||
#define R_MIPS_CALLHI16 30
|
||||
#define R_MIPS_CALLLO16 31
|
||||
/*
|
||||
* This range is reserved for vendor specific relocations.
|
||||
*/
|
||||
#define R_MIPS_LOVENDOR 100
|
||||
#define R_MIPS_HIVENDOR 127
|
||||
|
||||
|
||||
/*
|
||||
* Sparc ELF relocation types
|
||||
*/
|
||||
#define R_SPARC_NONE 0
|
||||
#define R_SPARC_8 1
|
||||
#define R_SPARC_16 2
|
||||
#define R_SPARC_32 3
|
||||
#define R_SPARC_DISP8 4
|
||||
#define R_SPARC_DISP16 5
|
||||
#define R_SPARC_DISP32 6
|
||||
#define R_SPARC_WDISP30 7
|
||||
#define R_SPARC_WDISP22 8
|
||||
#define R_SPARC_HI22 9
|
||||
#define R_SPARC_22 10
|
||||
#define R_SPARC_13 11
|
||||
#define R_SPARC_LO10 12
|
||||
#define R_SPARC_GOT10 13
|
||||
#define R_SPARC_GOT13 14
|
||||
#define R_SPARC_GOT22 15
|
||||
#define R_SPARC_PC10 16
|
||||
#define R_SPARC_PC22 17
|
||||
#define R_SPARC_WPLT30 18
|
||||
#define R_SPARC_COPY 19
|
||||
#define R_SPARC_GLOB_DAT 20
|
||||
#define R_SPARC_JMP_SLOT 21
|
||||
#define R_SPARC_RELATIVE 22
|
||||
#define R_SPARC_UA32 23
|
||||
#define R_SPARC_PLT32 24
|
||||
#define R_SPARC_HIPLT22 25
|
||||
#define R_SPARC_LOPLT10 26
|
||||
#define R_SPARC_PCPLT32 27
|
||||
#define R_SPARC_PCPLT22 28
|
||||
#define R_SPARC_PCPLT10 29
|
||||
#define R_SPARC_10 30
|
||||
#define R_SPARC_11 31
|
||||
#define R_SPARC_64 32
|
||||
#define R_SPARC_WDISP16 40
|
||||
#define R_SPARC_WDISP19 41
|
||||
#define R_SPARC_7 43
|
||||
#define R_SPARC_5 44
|
||||
#define R_SPARC_6 45
|
||||
|
||||
/* Bits present in AT_HWCAP, primarily for Sparc32. */
|
||||
|
||||
#define HWCAP_SPARC_FLUSH 1 /* CPU supports flush instruction. */
|
||||
#define HWCAP_SPARC_STBAR 2
|
||||
#define HWCAP_SPARC_SWAP 4
|
||||
#define HWCAP_SPARC_MULDIV 8
|
||||
#define HWCAP_SPARC_V9 16
|
||||
#define HWCAP_SPARC_ULTRA3 32
|
||||
|
||||
/*
|
||||
* 68k ELF relocation types
|
||||
*/
|
||||
#define R_68K_NONE 0
|
||||
#define R_68K_32 1
|
||||
#define R_68K_16 2
|
||||
#define R_68K_8 3
|
||||
#define R_68K_PC32 4
|
||||
#define R_68K_PC16 5
|
||||
#define R_68K_PC8 6
|
||||
#define R_68K_GOT32 7
|
||||
#define R_68K_GOT16 8
|
||||
#define R_68K_GOT8 9
|
||||
#define R_68K_GOT32O 10
|
||||
#define R_68K_GOT16O 11
|
||||
#define R_68K_GOT8O 12
|
||||
#define R_68K_PLT32 13
|
||||
#define R_68K_PLT16 14
|
||||
#define R_68K_PLT8 15
|
||||
#define R_68K_PLT32O 16
|
||||
#define R_68K_PLT16O 17
|
||||
#define R_68K_PLT8O 18
|
||||
#define R_68K_COPY 19
|
||||
#define R_68K_GLOB_DAT 20
|
||||
#define R_68K_JMP_SLOT 21
|
||||
#define R_68K_RELATIVE 22
|
||||
|
||||
/*
|
||||
* Alpha ELF relocation types
|
||||
*/
|
||||
#define R_ALPHA_NONE 0 /* No reloc */
|
||||
#define R_ALPHA_REFLONG 1 /* Direct 32 bit */
|
||||
#define R_ALPHA_REFQUAD 2 /* Direct 64 bit */
|
||||
#define R_ALPHA_GPREL32 3 /* GP relative 32 bit */
|
||||
#define R_ALPHA_LITERAL 4 /* GP relative 16 bit w/optimization */
|
||||
#define R_ALPHA_LITUSE 5 /* Optimization hint for LITERAL */
|
||||
#define R_ALPHA_GPDISP 6 /* Add displacement to GP */
|
||||
#define R_ALPHA_BRADDR 7 /* PC+4 relative 23 bit shifted */
|
||||
#define R_ALPHA_HINT 8 /* PC+4 relative 16 bit shifted */
|
||||
#define R_ALPHA_SREL16 9 /* PC relative 16 bit */
|
||||
#define R_ALPHA_SREL32 10 /* PC relative 32 bit */
|
||||
#define R_ALPHA_SREL64 11 /* PC relative 64 bit */
|
||||
#define R_ALPHA_GPRELHIGH 17 /* GP relative 32 bit, high 16 bits */
|
||||
#define R_ALPHA_GPRELLOW 18 /* GP relative 32 bit, low 16 bits */
|
||||
#define R_ALPHA_GPREL16 19 /* GP relative 16 bit */
|
||||
#define R_ALPHA_COPY 24 /* Copy symbol at runtime */
|
||||
#define R_ALPHA_GLOB_DAT 25 /* Create GOT entry */
|
||||
#define R_ALPHA_JMP_SLOT 26 /* Create PLT entry */
|
||||
#define R_ALPHA_RELATIVE 27 /* Adjust by program base */
|
||||
#define R_ALPHA_BRSGP 28
|
||||
#define R_ALPHA_TLSGD 29
|
||||
#define R_ALPHA_TLS_LDM 30
|
||||
#define R_ALPHA_DTPMOD64 31
|
||||
#define R_ALPHA_GOTDTPREL 32
|
||||
#define R_ALPHA_DTPREL64 33
|
||||
#define R_ALPHA_DTPRELHI 34
|
||||
#define R_ALPHA_DTPRELLO 35
|
||||
#define R_ALPHA_DTPREL16 36
|
||||
#define R_ALPHA_GOTTPREL 37
|
||||
#define R_ALPHA_TPREL64 38
|
||||
#define R_ALPHA_TPRELHI 39
|
||||
#define R_ALPHA_TPRELLO 40
|
||||
#define R_ALPHA_TPREL16 41
|
||||
|
||||
#define SHF_ALPHA_GPREL 0x10000000
|
||||
|
||||
|
||||
/* PowerPC relocations defined by the ABIs */
|
||||
#define R_PPC_NONE 0
|
||||
#define R_PPC_ADDR32 1 /* 32bit absolute address */
|
||||
#define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */
|
||||
#define R_PPC_ADDR16 3 /* 16bit absolute address */
|
||||
#define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */
|
||||
#define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */
|
||||
#define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */
|
||||
#define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */
|
||||
#define R_PPC_ADDR14_BRTAKEN 8
|
||||
#define R_PPC_ADDR14_BRNTAKEN 9
|
||||
#define R_PPC_REL24 10 /* PC relative 26 bit */
|
||||
#define R_PPC_REL14 11 /* PC relative 16 bit */
|
||||
#define R_PPC_REL14_BRTAKEN 12
|
||||
#define R_PPC_REL14_BRNTAKEN 13
|
||||
#define R_PPC_GOT16 14
|
||||
#define R_PPC_GOT16_LO 15
|
||||
#define R_PPC_GOT16_HI 16
|
||||
#define R_PPC_GOT16_HA 17
|
||||
#define R_PPC_PLTREL24 18
|
||||
#define R_PPC_COPY 19
|
||||
#define R_PPC_GLOB_DAT 20
|
||||
#define R_PPC_JMP_SLOT 21
|
||||
#define R_PPC_RELATIVE 22
|
||||
#define R_PPC_LOCAL24PC 23
|
||||
#define R_PPC_UADDR32 24
|
||||
#define R_PPC_UADDR16 25
|
||||
#define R_PPC_REL32 26
|
||||
#define R_PPC_PLT32 27
|
||||
#define R_PPC_PLTREL32 28
|
||||
#define R_PPC_PLT16_LO 29
|
||||
#define R_PPC_PLT16_HI 30
|
||||
#define R_PPC_PLT16_HA 31
|
||||
#define R_PPC_SDAREL16 32
|
||||
#define R_PPC_SECTOFF 33
|
||||
#define R_PPC_SECTOFF_LO 34
|
||||
#define R_PPC_SECTOFF_HI 35
|
||||
#define R_PPC_SECTOFF_HA 36
|
||||
/* Keep this the last entry. */
|
||||
#define R_PPC_NUM 37
|
||||
|
||||
/* ARM specific declarations */
|
||||
|
||||
/* Processor specific flags for the ELF header e_flags field. */
|
||||
#define EF_ARM_RELEXEC 0x01
|
||||
#define EF_ARM_HASENTRY 0x02
|
||||
#define EF_ARM_INTERWORK 0x04
|
||||
#define EF_ARM_APCS_26 0x08
|
||||
#define EF_ARM_APCS_FLOAT 0x10
|
||||
#define EF_ARM_PIC 0x20
|
||||
#define EF_ALIGN8 0x40 /* 8-bit structure alignment is in use */
|
||||
#define EF_NEW_ABI 0x80
|
||||
#define EF_OLD_ABI 0x100
|
||||
|
||||
/* Additional symbol types for Thumb */
|
||||
#define STT_ARM_TFUNC 0xd
|
||||
|
||||
/* ARM-specific values for sh_flags */
|
||||
#define SHF_ARM_ENTRYSECT 0x10000000 /* Section contains an entry point */
|
||||
#define SHF_ARM_COMDEF 0x80000000 /* Section may be multiply defined
|
||||
in the input to a link step */
|
||||
|
||||
/* ARM-specific program header flags */
|
||||
#define PF_ARM_SB 0x10000000 /* Segment contains the location
|
||||
addressed by the static base */
|
||||
|
||||
/* ARM relocs. */
|
||||
#define R_ARM_NONE 0 /* No reloc */
|
||||
#define R_ARM_PC24 1 /* PC relative 26 bit branch */
|
||||
#define R_ARM_ABS32 2 /* Direct 32 bit */
|
||||
#define R_ARM_REL32 3 /* PC relative 32 bit */
|
||||
#define R_ARM_PC13 4
|
||||
#define R_ARM_ABS16 5 /* Direct 16 bit */
|
||||
#define R_ARM_ABS12 6 /* Direct 12 bit */
|
||||
#define R_ARM_THM_ABS5 7
|
||||
#define R_ARM_ABS8 8 /* Direct 8 bit */
|
||||
#define R_ARM_SBREL32 9
|
||||
#define R_ARM_THM_PC22 10
|
||||
#define R_ARM_THM_PC8 11
|
||||
#define R_ARM_AMP_VCALL9 12
|
||||
#define R_ARM_SWI24 13
|
||||
#define R_ARM_THM_SWI8 14
|
||||
#define R_ARM_XPC25 15
|
||||
#define R_ARM_THM_XPC22 16
|
||||
#define R_ARM_COPY 20 /* Copy symbol at runtime */
|
||||
#define R_ARM_GLOB_DAT 21 /* Create GOT entry */
|
||||
#define R_ARM_JUMP_SLOT 22 /* Create PLT entry */
|
||||
#define R_ARM_RELATIVE 23 /* Adjust by program base */
|
||||
#define R_ARM_GOTOFF 24 /* 32 bit offset to GOT */
|
||||
#define R_ARM_GOTPC 25 /* 32 bit PC relative offset to GOT */
|
||||
#define R_ARM_GOT32 26 /* 32 bit GOT entry */
|
||||
#define R_ARM_PLT32 27 /* 32 bit PLT address */
|
||||
#define R_ARM_GNU_VTENTRY 100
|
||||
#define R_ARM_GNU_VTINHERIT 101
|
||||
#define R_ARM_THM_PC11 102 /* thumb unconditional branch */
|
||||
#define R_ARM_THM_PC9 103 /* thumb conditional branch */
|
||||
#define R_ARM_RXPC25 249
|
||||
#define R_ARM_RSBREL32 250
|
||||
#define R_ARM_THM_RPC22 251
|
||||
#define R_ARM_RREL32 252
|
||||
#define R_ARM_RABS22 253
|
||||
#define R_ARM_RPC24 254
|
||||
#define R_ARM_RBASE 255
|
||||
/* Keep this the last entry. */
|
||||
#define R_ARM_NUM 256
|
||||
|
||||
/* s390 relocations defined by the ABIs */
|
||||
#define R_390_NONE 0 /* No reloc. */
|
||||
#define R_390_8 1 /* Direct 8 bit. */
|
||||
#define R_390_12 2 /* Direct 12 bit. */
|
||||
#define R_390_16 3 /* Direct 16 bit. */
|
||||
#define R_390_32 4 /* Direct 32 bit. */
|
||||
#define R_390_PC32 5 /* PC relative 32 bit. */
|
||||
#define R_390_GOT12 6 /* 12 bit GOT offset. */
|
||||
#define R_390_GOT32 7 /* 32 bit GOT offset. */
|
||||
#define R_390_PLT32 8 /* 32 bit PC relative PLT address. */
|
||||
#define R_390_COPY 9 /* Copy symbol at runtime. */
|
||||
#define R_390_GLOB_DAT 10 /* Create GOT entry. */
|
||||
#define R_390_JMP_SLOT 11 /* Create PLT entry. */
|
||||
#define R_390_RELATIVE 12 /* Adjust by program base. */
|
||||
#define R_390_GOTOFF32 13 /* 32 bit offset to GOT. */
|
||||
#define R_390_GOTPC 14 /* 32 bit PC rel. offset to GOT. */
|
||||
#define R_390_GOT16 15 /* 16 bit GOT offset. */
|
||||
#define R_390_PC16 16 /* PC relative 16 bit. */
|
||||
#define R_390_PC16DBL 17 /* PC relative 16 bit shifted by 1. */
|
||||
#define R_390_PLT16DBL 18 /* 16 bit PC rel. PLT shifted by 1. */
|
||||
#define R_390_PC32DBL 19 /* PC relative 32 bit shifted by 1. */
|
||||
#define R_390_PLT32DBL 20 /* 32 bit PC rel. PLT shifted by 1. */
|
||||
#define R_390_GOTPCDBL 21 /* 32 bit PC rel. GOT shifted by 1. */
|
||||
#define R_390_64 22 /* Direct 64 bit. */
|
||||
#define R_390_PC64 23 /* PC relative 64 bit. */
|
||||
#define R_390_GOT64 24 /* 64 bit GOT offset. */
|
||||
#define R_390_PLT64 25 /* 64 bit PC relative PLT address. */
|
||||
#define R_390_GOTENT 26 /* 32 bit PC rel. to GOT entry >> 1. */
|
||||
#define R_390_GOTOFF16 27 /* 16 bit offset to GOT. */
|
||||
#define R_390_GOTOFF64 28 /* 64 bit offset to GOT. */
|
||||
#define R_390_GOTPLT12 29 /* 12 bit offset to jump slot. */
|
||||
#define R_390_GOTPLT16 30 /* 16 bit offset to jump slot. */
|
||||
#define R_390_GOTPLT32 31 /* 32 bit offset to jump slot. */
|
||||
#define R_390_GOTPLT64 32 /* 64 bit offset to jump slot. */
|
||||
#define R_390_GOTPLTENT 33 /* 32 bit rel. offset to jump slot. */
|
||||
#define R_390_PLTOFF16 34 /* 16 bit offset from GOT to PLT. */
|
||||
#define R_390_PLTOFF32 35 /* 32 bit offset from GOT to PLT. */
|
||||
#define R_390_PLTOFF64 36 /* 16 bit offset from GOT to PLT. */
|
||||
#define R_390_TLS_LOAD 37 /* Tag for load insn in TLS code. */
|
||||
#define R_390_TLS_GDCALL 38 /* Tag for function call in general
|
||||
dynamic TLS code. */
|
||||
#define R_390_TLS_LDCALL 39 /* Tag for function call in local
|
||||
dynamic TLS code. */
|
||||
#define R_390_TLS_GD32 40 /* Direct 32 bit for general dynamic
|
||||
thread local data. */
|
||||
#define R_390_TLS_GD64 41 /* Direct 64 bit for general dynamic
|
||||
thread local data. */
|
||||
#define R_390_TLS_GOTIE12 42 /* 12 bit GOT offset for static TLS
|
||||
block offset. */
|
||||
#define R_390_TLS_GOTIE32 43 /* 32 bit GOT offset for static TLS
|
||||
block offset. */
|
||||
#define R_390_TLS_GOTIE64 44 /* 64 bit GOT offset for static TLS
|
||||
block offset. */
|
||||
#define R_390_TLS_LDM32 45 /* Direct 32 bit for local dynamic
|
||||
thread local data in LD code. */
|
||||
#define R_390_TLS_LDM64 46 /* Direct 64 bit for local dynamic
|
||||
thread local data in LD code. */
|
||||
#define R_390_TLS_IE32 47 /* 32 bit address of GOT entry for
|
||||
negated static TLS block offset. */
|
||||
#define R_390_TLS_IE64 48 /* 64 bit address of GOT entry for
|
||||
negated static TLS block offset. */
|
||||
#define R_390_TLS_IEENT 49 /* 32 bit rel. offset to GOT entry for
|
||||
negated static TLS block offset. */
|
||||
#define R_390_TLS_LE32 50 /* 32 bit negated offset relative to
|
||||
static TLS block. */
|
||||
#define R_390_TLS_LE64 51 /* 64 bit negated offset relative to
|
||||
static TLS block. */
|
||||
#define R_390_TLS_LDO32 52 /* 32 bit offset relative to TLS
|
||||
block. */
|
||||
#define R_390_TLS_LDO64 53 /* 64 bit offset relative to TLS
|
||||
block. */
|
||||
#define R_390_TLS_DTPMOD 54 /* ID of module containing symbol. */
|
||||
#define R_390_TLS_DTPOFF 55 /* Offset in TLS block. */
|
||||
#define R_390_TLS_TPOFF 56 /* Negate offset in static TLS
|
||||
block. */
|
||||
/* Keep this the last entry. */
|
||||
#define R_390_NUM 57
|
||||
|
||||
/* x86-64 relocation types */
|
||||
#define R_X86_64_NONE 0 /* No reloc */
|
||||
#define R_X86_64_64 1 /* Direct 64 bit */
|
||||
#define R_X86_64_PC32 2 /* PC relative 32 bit signed */
|
||||
#define R_X86_64_GOT32 3 /* 32 bit GOT entry */
|
||||
#define R_X86_64_PLT32 4 /* 32 bit PLT address */
|
||||
#define R_X86_64_COPY 5 /* Copy symbol at runtime */
|
||||
#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */
|
||||
#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */
|
||||
#define R_X86_64_RELATIVE 8 /* Adjust by program base */
|
||||
#define R_X86_64_GOTPCREL 9 /* 32 bit signed pc relative
|
||||
offset to GOT */
|
||||
#define R_X86_64_32 10 /* Direct 32 bit zero extended */
|
||||
#define R_X86_64_32S 11 /* Direct 32 bit sign extended */
|
||||
#define R_X86_64_16 12 /* Direct 16 bit zero extended */
|
||||
#define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */
|
||||
#define R_X86_64_8 14 /* Direct 8 bit sign extended */
|
||||
#define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */
|
||||
|
||||
#define R_X86_64_NUM 16
|
||||
|
||||
/* Legal values for e_flags field of Elf64_Ehdr. */
|
||||
|
||||
#define EF_ALPHA_32BIT 1 /* All addresses are below 2GB */
|
||||
|
||||
/* HPPA specific definitions. */
|
||||
|
||||
/* Legal values for e_flags field of Elf32_Ehdr. */
|
||||
|
||||
#define EF_PARISC_TRAPNIL 0x00010000 /* Trap nil pointer dereference. */
|
||||
#define EF_PARISC_EXT 0x00020000 /* Program uses arch. extensions. */
|
||||
#define EF_PARISC_LSB 0x00040000 /* Program expects little endian. */
|
||||
#define EF_PARISC_WIDE 0x00080000 /* Program expects wide mode. */
|
||||
#define EF_PARISC_NO_KABP 0x00100000 /* No kernel assisted branch
|
||||
prediction. */
|
||||
#define EF_PARISC_LAZYSWAP 0x00400000 /* Allow lazy swapping. */
|
||||
#define EF_PARISC_ARCH 0x0000ffff /* Architecture version. */
|
||||
|
||||
/* Defined values for `e_flags & EF_PARISC_ARCH' are: */
|
||||
|
||||
#define EFA_PARISC_1_0 0x020b /* PA-RISC 1.0 big-endian. */
|
||||
#define EFA_PARISC_1_1 0x0210 /* PA-RISC 1.1 big-endian. */
|
||||
#define EFA_PARISC_2_0 0x0214 /* PA-RISC 2.0 big-endian. */
|
||||
|
||||
/* Additional section indeces. */
|
||||
|
||||
#define SHN_PARISC_ANSI_COMMON 0xff00 /* Section for tenatively declared
|
||||
symbols in ANSI C. */
|
||||
#define SHN_PARISC_HUGE_COMMON 0xff01 /* Common blocks in huge model. */
|
||||
|
||||
/* Legal values for sh_type field of Elf32_Shdr. */
|
||||
|
||||
#define SHT_PARISC_EXT 0x70000000 /* Contains product specific ext. */
|
||||
#define SHT_PARISC_UNWIND 0x70000001 /* Unwind information. */
|
||||
#define SHT_PARISC_DOC 0x70000002 /* Debug info for optimized code. */
|
||||
|
||||
/* Legal values for sh_flags field of Elf32_Shdr. */
|
||||
|
||||
#define SHF_PARISC_SHORT 0x20000000 /* Section with short addressing. */
|
||||
#define SHF_PARISC_HUGE 0x40000000 /* Section far from gp. */
|
||||
#define SHF_PARISC_SBP 0x80000000 /* Static branch prediction code. */
|
||||
|
||||
/* Legal values for ST_TYPE subfield of st_info (symbol type). */
|
||||
|
||||
#define STT_PARISC_MILLICODE 13 /* Millicode function entry point. */
|
||||
|
||||
#define STT_HP_OPAQUE (STT_LOOS + 0x1)
|
||||
#define STT_HP_STUB (STT_LOOS + 0x2)
|
||||
|
||||
/* HPPA relocs. */
|
||||
|
||||
#define R_PARISC_NONE 0 /* No reloc. */
|
||||
#define R_PARISC_DIR32 1 /* Direct 32-bit reference. */
|
||||
#define R_PARISC_DIR21L 2 /* Left 21 bits of eff. address. */
|
||||
#define R_PARISC_DIR17R 3 /* Right 17 bits of eff. address. */
|
||||
#define R_PARISC_DIR17F 4 /* 17 bits of eff. address. */
|
||||
#define R_PARISC_DIR14R 6 /* Right 14 bits of eff. address. */
|
||||
#define R_PARISC_PCREL32 9 /* 32-bit rel. address. */
|
||||
#define R_PARISC_PCREL21L 10 /* Left 21 bits of rel. address. */
|
||||
#define R_PARISC_PCREL17R 11 /* Right 17 bits of rel. address. */
|
||||
#define R_PARISC_PCREL17F 12 /* 17 bits of rel. address. */
|
||||
#define R_PARISC_PCREL14R 14 /* Right 14 bits of rel. address. */
|
||||
#define R_PARISC_DPREL21L 18 /* Left 21 bits of rel. address. */
|
||||
#define R_PARISC_DPREL14R 22 /* Right 14 bits of rel. address. */
|
||||
#define R_PARISC_GPREL21L 26 /* GP-relative, left 21 bits. */
|
||||
#define R_PARISC_GPREL14R 30 /* GP-relative, right 14 bits. */
|
||||
#define R_PARISC_LTOFF21L 34 /* LT-relative, left 21 bits. */
|
||||
#define R_PARISC_LTOFF14R 38 /* LT-relative, right 14 bits. */
|
||||
#define R_PARISC_SECREL32 41 /* 32 bits section rel. address. */
|
||||
#define R_PARISC_SEGBASE 48 /* No relocation, set segment base. */
|
||||
#define R_PARISC_SEGREL32 49 /* 32 bits segment rel. address. */
|
||||
#define R_PARISC_PLTOFF21L 50 /* PLT rel. address, left 21 bits. */
|
||||
#define R_PARISC_PLTOFF14R 54 /* PLT rel. address, right 14 bits. */
|
||||
#define R_PARISC_LTOFF_FPTR32 57 /* 32 bits LT-rel. function pointer. */
|
||||
#define R_PARISC_LTOFF_FPTR21L 58 /* LT-rel. fct ptr, left 21 bits. */
|
||||
#define R_PARISC_LTOFF_FPTR14R 62 /* LT-rel. fct ptr, right 14 bits. */
|
||||
#define R_PARISC_FPTR64 64 /* 64 bits function address. */
|
||||
#define R_PARISC_PLABEL32 65 /* 32 bits function address. */
|
||||
#define R_PARISC_PCREL64 72 /* 64 bits PC-rel. address. */
|
||||
#define R_PARISC_PCREL22F 74 /* 22 bits PC-rel. address. */
|
||||
#define R_PARISC_PCREL14WR 75 /* PC-rel. address, right 14 bits. */
|
||||
#define R_PARISC_PCREL14DR 76 /* PC rel. address, right 14 bits. */
|
||||
#define R_PARISC_PCREL16F 77 /* 16 bits PC-rel. address. */
|
||||
#define R_PARISC_PCREL16WF 78 /* 16 bits PC-rel. address. */
|
||||
#define R_PARISC_PCREL16DF 79 /* 16 bits PC-rel. address. */
|
||||
#define R_PARISC_DIR64 80 /* 64 bits of eff. address. */
|
||||
#define R_PARISC_DIR14WR 83 /* 14 bits of eff. address. */
|
||||
#define R_PARISC_DIR14DR 84 /* 14 bits of eff. address. */
|
||||
#define R_PARISC_DIR16F 85 /* 16 bits of eff. address. */
|
||||
#define R_PARISC_DIR16WF 86 /* 16 bits of eff. address. */
|
||||
#define R_PARISC_DIR16DF 87 /* 16 bits of eff. address. */
|
||||
#define R_PARISC_GPREL64 88 /* 64 bits of GP-rel. address. */
|
||||
#define R_PARISC_GPREL14WR 91 /* GP-rel. address, right 14 bits. */
|
||||
#define R_PARISC_GPREL14DR 92 /* GP-rel. address, right 14 bits. */
|
||||
#define R_PARISC_GPREL16F 93 /* 16 bits GP-rel. address. */
|
||||
#define R_PARISC_GPREL16WF 94 /* 16 bits GP-rel. address. */
|
||||
#define R_PARISC_GPREL16DF 95 /* 16 bits GP-rel. address. */
|
||||
#define R_PARISC_LTOFF64 96 /* 64 bits LT-rel. address. */
|
||||
#define R_PARISC_LTOFF14WR 99 /* LT-rel. address, right 14 bits. */
|
||||
#define R_PARISC_LTOFF14DR 100 /* LT-rel. address, right 14 bits. */
|
||||
#define R_PARISC_LTOFF16F 101 /* 16 bits LT-rel. address. */
|
||||
#define R_PARISC_LTOFF16WF 102 /* 16 bits LT-rel. address. */
|
||||
#define R_PARISC_LTOFF16DF 103 /* 16 bits LT-rel. address. */
|
||||
#define R_PARISC_SECREL64 104 /* 64 bits section rel. address. */
|
||||
#define R_PARISC_SEGREL64 112 /* 64 bits segment rel. address. */
|
||||
#define R_PARISC_PLTOFF14WR 115 /* PLT-rel. address, right 14 bits. */
|
||||
#define R_PARISC_PLTOFF14DR 116 /* PLT-rel. address, right 14 bits. */
|
||||
#define R_PARISC_PLTOFF16F 117 /* 16 bits LT-rel. address. */
|
||||
#define R_PARISC_PLTOFF16WF 118 /* 16 bits PLT-rel. address. */
|
||||
#define R_PARISC_PLTOFF16DF 119 /* 16 bits PLT-rel. address. */
|
||||
#define R_PARISC_LTOFF_FPTR64 120 /* 64 bits LT-rel. function ptr. */
|
||||
#define R_PARISC_LTOFF_FPTR14WR 123 /* LT-rel. fct. ptr., right 14 bits. */
|
||||
#define R_PARISC_LTOFF_FPTR14DR 124 /* LT-rel. fct. ptr., right 14 bits. */
|
||||
#define R_PARISC_LTOFF_FPTR16F 125 /* 16 bits LT-rel. function ptr. */
|
||||
#define R_PARISC_LTOFF_FPTR16WF 126 /* 16 bits LT-rel. function ptr. */
|
||||
#define R_PARISC_LTOFF_FPTR16DF 127 /* 16 bits LT-rel. function ptr. */
|
||||
#define R_PARISC_LORESERVE 128
|
||||
#define R_PARISC_COPY 128 /* Copy relocation. */
|
||||
#define R_PARISC_IPLT 129 /* Dynamic reloc, imported PLT */
|
||||
#define R_PARISC_EPLT 130 /* Dynamic reloc, exported PLT */
|
||||
#define R_PARISC_TPREL32 153 /* 32 bits TP-rel. address. */
|
||||
#define R_PARISC_TPREL21L 154 /* TP-rel. address, left 21 bits. */
|
||||
#define R_PARISC_TPREL14R 158 /* TP-rel. address, right 14 bits. */
|
||||
#define R_PARISC_LTOFF_TP21L 162 /* LT-TP-rel. address, left 21 bits. */
|
||||
#define R_PARISC_LTOFF_TP14R 166 /* LT-TP-rel. address, right 14 bits.*/
|
||||
#define R_PARISC_LTOFF_TP14F 167 /* 14 bits LT-TP-rel. address. */
|
||||
#define R_PARISC_TPREL64 216 /* 64 bits TP-rel. address. */
|
||||
#define R_PARISC_TPREL14WR 219 /* TP-rel. address, right 14 bits. */
|
||||
#define R_PARISC_TPREL14DR 220 /* TP-rel. address, right 14 bits. */
|
||||
#define R_PARISC_TPREL16F 221 /* 16 bits TP-rel. address. */
|
||||
#define R_PARISC_TPREL16WF 222 /* 16 bits TP-rel. address. */
|
||||
#define R_PARISC_TPREL16DF 223 /* 16 bits TP-rel. address. */
|
||||
#define R_PARISC_LTOFF_TP64 224 /* 64 bits LT-TP-rel. address. */
|
||||
#define R_PARISC_LTOFF_TP14WR 227 /* LT-TP-rel. address, right 14 bits.*/
|
||||
#define R_PARISC_LTOFF_TP14DR 228 /* LT-TP-rel. address, right 14 bits.*/
|
||||
#define R_PARISC_LTOFF_TP16F 229 /* 16 bits LT-TP-rel. address. */
|
||||
#define R_PARISC_LTOFF_TP16WF 230 /* 16 bits LT-TP-rel. address. */
|
||||
#define R_PARISC_LTOFF_TP16DF 231 /* 16 bits LT-TP-rel. address. */
|
||||
#define R_PARISC_HIRESERVE 255
|
||||
|
||||
/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr. */
|
||||
|
||||
#define PT_HP_TLS (PT_LOOS + 0x0)
|
||||
#define PT_HP_CORE_NONE (PT_LOOS + 0x1)
|
||||
#define PT_HP_CORE_VERSION (PT_LOOS + 0x2)
|
||||
#define PT_HP_CORE_KERNEL (PT_LOOS + 0x3)
|
||||
#define PT_HP_CORE_COMM (PT_LOOS + 0x4)
|
||||
#define PT_HP_CORE_PROC (PT_LOOS + 0x5)
|
||||
#define PT_HP_CORE_LOADABLE (PT_LOOS + 0x6)
|
||||
#define PT_HP_CORE_STACK (PT_LOOS + 0x7)
|
||||
#define PT_HP_CORE_SHM (PT_LOOS + 0x8)
|
||||
#define PT_HP_CORE_MMF (PT_LOOS + 0x9)
|
||||
#define PT_HP_PARALLEL (PT_LOOS + 0x10)
|
||||
#define PT_HP_FASTBIND (PT_LOOS + 0x11)
|
||||
#define PT_HP_OPT_ANNOT (PT_LOOS + 0x12)
|
||||
#define PT_HP_HSL_ANNOT (PT_LOOS + 0x13)
|
||||
#define PT_HP_STACK (PT_LOOS + 0x14)
|
||||
|
||||
#define PT_PARISC_ARCHEXT 0x70000000
|
||||
#define PT_PARISC_UNWIND 0x70000001
|
||||
|
||||
/* Legal values for p_flags field of Elf32_Phdr/Elf64_Phdr. */
|
||||
|
||||
#define PF_PARISC_SBP 0x08000000
|
||||
|
||||
#define PF_HP_PAGE_SIZE 0x00100000
|
||||
#define PF_HP_FAR_SHARED 0x00200000
|
||||
#define PF_HP_NEAR_SHARED 0x00400000
|
||||
#define PF_HP_CODE 0x01000000
|
||||
#define PF_HP_MODIFY 0x02000000
|
||||
#define PF_HP_LAZYSWAP 0x04000000
|
||||
#define PF_HP_SBP 0x08000000
|
||||
|
||||
|
||||
typedef struct elf32_rel {
|
||||
Elf32_Addr r_offset;
|
||||
Elf32_Word r_info;
|
||||
} Elf32_Rel;
|
||||
|
||||
typedef struct elf64_rel {
|
||||
unsigned long long r_offset; /* Location at which to apply the action */
|
||||
unsigned long long r_info; /* index and type of relocation */
|
||||
Elf64_Addr r_offset; /* Location at which to apply the action */
|
||||
Elf64_Xword r_info; /* index and type of relocation */
|
||||
} Elf64_Rel;
|
||||
|
||||
typedef struct elf32_rela{
|
||||
@@ -202,9 +785,9 @@ typedef struct elf32_rela{
|
||||
} Elf32_Rela;
|
||||
|
||||
typedef struct elf64_rela {
|
||||
unsigned long long r_offset; /* Location at which to apply the action */
|
||||
unsigned long long r_info; /* index and type of relocation */
|
||||
unsigned long long r_addend; /* Constant addend used to compute value */
|
||||
Elf64_Addr r_offset; /* Location at which to apply the action */
|
||||
Elf64_Xword r_info; /* index and type of relocation */
|
||||
Elf64_Sxword r_addend; /* Constant addend used to compute value */
|
||||
} Elf64_Rela;
|
||||
|
||||
typedef struct elf32_sym{
|
||||
@@ -217,12 +800,12 @@ typedef struct elf32_sym{
|
||||
} Elf32_Sym;
|
||||
|
||||
typedef struct elf64_sym {
|
||||
unsigned int st_name; /* Symbol name, index in string tbl */
|
||||
Elf64_Word st_name; /* Symbol name, index in string tbl */
|
||||
unsigned char st_info; /* Type and binding attributes */
|
||||
unsigned char st_other; /* No defined meaning, 0 */
|
||||
unsigned short st_shndx; /* Associated section index */
|
||||
unsigned long long st_value; /* Value of the symbol */
|
||||
unsigned long long st_size; /* Associated symbol size */
|
||||
Elf64_Half st_shndx; /* Associated section index */
|
||||
Elf64_Addr st_value; /* Value of the symbol */
|
||||
Elf64_Xword st_size; /* Associated symbol size */
|
||||
} Elf64_Sym;
|
||||
|
||||
|
||||
@@ -247,19 +830,19 @@ typedef struct elf32_hdr{
|
||||
|
||||
typedef struct elf64_hdr {
|
||||
unsigned char e_ident[16]; /* ELF "magic number" */
|
||||
short int e_type;
|
||||
short unsigned int e_machine;
|
||||
int e_version;
|
||||
unsigned long long e_entry; /* Entry point virtual address */
|
||||
unsigned long long e_phoff; /* Program header table file offset */
|
||||
unsigned long long e_shoff; /* Section header table file offset */
|
||||
int e_flags;
|
||||
short int e_ehsize;
|
||||
short int e_phentsize;
|
||||
short int e_phnum;
|
||||
short int e_shentsize;
|
||||
short int e_shnum;
|
||||
short int e_shstrndx;
|
||||
Elf64_Half e_type;
|
||||
Elf64_Half e_machine;
|
||||
Elf64_Word e_version;
|
||||
Elf64_Addr e_entry; /* Entry point virtual address */
|
||||
Elf64_Off e_phoff; /* Program header table file offset */
|
||||
Elf64_Off e_shoff; /* Section header table file offset */
|
||||
Elf64_Word e_flags;
|
||||
Elf64_Half e_ehsize;
|
||||
Elf64_Half e_phentsize;
|
||||
Elf64_Half e_phnum;
|
||||
Elf64_Half e_shentsize;
|
||||
Elf64_Half e_shnum;
|
||||
Elf64_Half e_shstrndx;
|
||||
} Elf64_Ehdr;
|
||||
|
||||
/* These constants define the permissions on sections in the program
|
||||
@@ -280,14 +863,14 @@ typedef struct elf32_phdr{
|
||||
} Elf32_Phdr;
|
||||
|
||||
typedef struct elf64_phdr {
|
||||
int p_type;
|
||||
int p_flags;
|
||||
unsigned long long p_offset; /* Segment file offset */
|
||||
unsigned long long p_vaddr; /* Segment virtual address */
|
||||
unsigned long long p_paddr; /* Segment physical address */
|
||||
unsigned long long p_filesz; /* Segment size in file */
|
||||
unsigned long long p_memsz; /* Segment size in memory */
|
||||
unsigned long long p_align; /* Segment alignment, file & memory */
|
||||
Elf64_Word p_type;
|
||||
Elf64_Word p_flags;
|
||||
Elf64_Off p_offset; /* Segment file offset */
|
||||
Elf64_Addr p_vaddr; /* Segment virtual address */
|
||||
Elf64_Addr p_paddr; /* Segment physical address */
|
||||
Elf64_Xword p_filesz; /* Segment size in file */
|
||||
Elf64_Xword p_memsz; /* Segment size in memory */
|
||||
Elf64_Xword p_align; /* Segment alignment, file & memory */
|
||||
} Elf64_Phdr;
|
||||
|
||||
/* sh_type */
|
||||
@@ -308,12 +891,17 @@ typedef struct elf64_phdr {
|
||||
#define SHT_HIPROC 0x7fffffff
|
||||
#define SHT_LOUSER 0x80000000
|
||||
#define SHT_HIUSER 0xffffffff
|
||||
#define SHT_MIPS_LIST 0x70000000
|
||||
#define SHT_MIPS_CONFLICT 0x70000002
|
||||
#define SHT_MIPS_GPTAB 0x70000003
|
||||
#define SHT_MIPS_UCODE 0x70000004
|
||||
|
||||
/* sh_flags */
|
||||
#define SHF_WRITE 0x1
|
||||
#define SHF_ALLOC 0x2
|
||||
#define SHF_EXECINSTR 0x4
|
||||
#define SHF_MASKPROC 0xf0000000
|
||||
#define SHF_MIPS_GPREL 0x10000000
|
||||
|
||||
/* special section indexes */
|
||||
#define SHN_UNDEF 0
|
||||
@@ -323,8 +911,9 @@ typedef struct elf64_phdr {
|
||||
#define SHN_ABS 0xfff1
|
||||
#define SHN_COMMON 0xfff2
|
||||
#define SHN_HIRESERVE 0xffff
|
||||
#define SHN_MIPS_ACCOMON 0xff00
|
||||
|
||||
typedef struct {
|
||||
typedef struct elf32_shdr {
|
||||
Elf32_Word sh_name;
|
||||
Elf32_Word sh_type;
|
||||
Elf32_Word sh_flags;
|
||||
@@ -338,16 +927,16 @@ typedef struct {
|
||||
} Elf32_Shdr;
|
||||
|
||||
typedef struct elf64_shdr {
|
||||
unsigned int sh_name; /* Section name, index in string tbl */
|
||||
unsigned int sh_type; /* Type of section */
|
||||
unsigned long long sh_flags; /* Miscellaneous section attributes */
|
||||
unsigned long long sh_addr; /* Section virtual addr at execution */
|
||||
unsigned long long sh_offset; /* Section file offset */
|
||||
unsigned long long sh_size; /* Size of section in bytes */
|
||||
unsigned int sh_link; /* Index of another section */
|
||||
unsigned int sh_info; /* Additional section information */
|
||||
unsigned long long sh_addralign; /* Section alignment */
|
||||
unsigned long long sh_entsize; /* Entry size if section holds table */
|
||||
Elf64_Word sh_name; /* Section name, index in string tbl */
|
||||
Elf64_Word sh_type; /* Type of section */
|
||||
Elf64_Xword sh_flags; /* Miscellaneous section attributes */
|
||||
Elf64_Addr sh_addr; /* Section virtual addr at execution */
|
||||
Elf64_Off sh_offset; /* Section file offset */
|
||||
Elf64_Xword sh_size; /* Size of section in bytes */
|
||||
Elf64_Word sh_link; /* Index of another section */
|
||||
Elf64_Word sh_info; /* Additional section information */
|
||||
Elf64_Xword sh_addralign; /* Section alignment */
|
||||
Elf64_Xword sh_entsize; /* Entry size if section holds table */
|
||||
} Elf64_Shdr;
|
||||
|
||||
#define EI_MAG0 0 /* e_ident[] indexes */
|
||||
@@ -384,6 +973,8 @@ typedef struct elf64_shdr {
|
||||
#define NT_PRFPREG 2
|
||||
#define NT_PRPSINFO 3
|
||||
#define NT_TASKSTRUCT 4
|
||||
#define NT_PRXFPREG 0x46e62b7f /* copied from gdb5.1/include/elf/common.h */
|
||||
|
||||
|
||||
/* Note header in a PT_NOTE section */
|
||||
typedef struct elf32_note {
|
||||
@@ -393,33 +984,49 @@ typedef struct elf32_note {
|
||||
} Elf32_Nhdr;
|
||||
|
||||
/* Note header in a PT_NOTE section */
|
||||
/*
|
||||
* For now we use the 32 bit version of the structure until we figure
|
||||
* out whether we need anything better. Note - on the Alpha, "unsigned int"
|
||||
* is only 32 bits.
|
||||
*/
|
||||
typedef struct elf64_note {
|
||||
unsigned int n_namesz; /* Name size */
|
||||
unsigned int n_descsz; /* Content size */
|
||||
unsigned int n_type; /* Content type */
|
||||
Elf64_Word n_namesz; /* Name size */
|
||||
Elf64_Word n_descsz; /* Content size */
|
||||
Elf64_Word n_type; /* Content type */
|
||||
} Elf64_Nhdr;
|
||||
|
||||
#define ELF_START_MMAP 0x80000000
|
||||
|
||||
#if ELF_CLASS == ELFCLASS32
|
||||
|
||||
extern Elf32_Dyn _DYNAMIC [];
|
||||
#define elfhdr elf32_hdr
|
||||
#define elf_phdr elf32_phdr
|
||||
#define elf_note elf32_note
|
||||
#define elf_shdr elf32_shdr
|
||||
|
||||
#ifdef ELF_USES_RELOCA
|
||||
# define ELF_RELOC Elf32_Rela
|
||||
#else
|
||||
# define ELF_RELOC Elf32_Rel
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
extern Elf64_Dyn _DYNAMIC [];
|
||||
#define elfhdr elf64_hdr
|
||||
#define elf_phdr elf64_phdr
|
||||
#define elf_note elf64_note
|
||||
#define elf_shdr elf64_shdr
|
||||
|
||||
#ifdef ELF_USES_RELOCA
|
||||
# define ELF_RELOC Elf64_Rela
|
||||
#else
|
||||
# define ELF_RELOC Elf64_Rel
|
||||
#endif
|
||||
|
||||
#endif /* ELF_CLASS */
|
||||
|
||||
#ifndef ElfW
|
||||
# if ELF_CLASS == ELFCLASS32
|
||||
# define ElfW(x) Elf32_ ## x
|
||||
# define ELFW(x) ELF32_ ## x
|
||||
# else
|
||||
# define ElfW(x) Elf64_ ## x
|
||||
# define ELFW(x) ELF64_ ## x
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _ELF_H */
|
||||
|
@@ -66,6 +66,7 @@ register unsigned int T1 asm("r25");
|
||||
register unsigned int A0 asm("r26");
|
||||
register struct CPUX86State *env asm("r27");
|
||||
#define USE_INT_TO_FLOAT_HELPERS
|
||||
#define BUGGY_GCC_DIV64
|
||||
#define reg_EAX
|
||||
#define reg_ECX
|
||||
#define reg_EDX
|
||||
@@ -99,6 +100,12 @@ register unsigned int T1 asm("r8");
|
||||
register unsigned int A0 asm("r9");
|
||||
register struct CPUX86State *env asm("r10");
|
||||
#endif
|
||||
#ifdef __alpha__
|
||||
register unsigned int T0 asm("$9");
|
||||
register unsigned int T1 asm("$10");
|
||||
register unsigned int A0 asm("$11");
|
||||
register struct CPUX86State *env asm("$12");
|
||||
#endif
|
||||
|
||||
/* force GCC to generate only one epilog at the end of the function */
|
||||
#define FORCE_RET() asm volatile ("");
|
||||
|
@@ -12,6 +12,43 @@
|
||||
|
||||
#include "qemu.h"
|
||||
|
||||
#ifdef TARGET_I386
|
||||
|
||||
#define ELF_START_MMAP 0x80000000
|
||||
|
||||
typedef uint32_t elf_greg_t;
|
||||
|
||||
#define ELF_NGREG (sizeof (struct target_pt_regs) / sizeof(elf_greg_t))
|
||||
typedef elf_greg_t elf_gregset_t[ELF_NGREG];
|
||||
|
||||
typedef struct user_i387_struct elf_fpregset_t;
|
||||
|
||||
/*
|
||||
* This is used to ensure we don't load something for the wrong architecture.
|
||||
*/
|
||||
#define elf_check_arch(x) ( ((x) == EM_386) || ((x) == EM_486) )
|
||||
|
||||
/*
|
||||
* These are used to set parameters in the core dumps.
|
||||
*/
|
||||
#define ELF_CLASS ELFCLASS32
|
||||
#define ELF_DATA ELFDATA2LSB
|
||||
#define ELF_ARCH EM_386
|
||||
|
||||
/* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program
|
||||
starts %edx contains a pointer to a function which might be
|
||||
registered using `atexit'. This provides a mean for the
|
||||
dynamic linker to call DT_FINI functions for shared libraries
|
||||
that have been loaded before the code runs.
|
||||
|
||||
A value of 0 tells we have no such handler. */
|
||||
#define ELF_PLAT_INIT(_r) _r->edx = 0
|
||||
|
||||
#define USE_ELF_CORE_DUMP
|
||||
#define ELF_EXEC_PAGESIZE 4096
|
||||
|
||||
#endif
|
||||
|
||||
#include "linux_bin.h"
|
||||
#include "elf.h"
|
||||
#include "segment.h"
|
||||
|
@@ -66,6 +66,7 @@
|
||||
IOCTL(FIGETBSZ, IOC_R, MK_PTR(TYPE_LONG))
|
||||
#endif
|
||||
|
||||
IOCTL(SIOCATMARK, 0, TYPE_NULL)
|
||||
IOCTL(SIOCADDRT, IOC_W, MK_PTR(MK_STRUCT(STRUCT_rtentry)))
|
||||
IOCTL(SIOCDELRT, IOC_W, MK_PTR(MK_STRUCT(STRUCT_rtentry)))
|
||||
IOCTL(SIOCGIFNAME, IOC_RW, MK_PTR(TYPE_INT))
|
||||
|
@@ -23,6 +23,9 @@
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)
|
||||
#include <sys/personality.h>
|
||||
#endif
|
||||
|
||||
#include "qemu.h"
|
||||
|
||||
@@ -34,6 +37,12 @@ FILE *logfile = NULL;
|
||||
int loglevel;
|
||||
const char *interp_prefix = CONFIG_QEMU_PREFIX "/qemu-i386";
|
||||
|
||||
#ifdef __i386__
|
||||
/* Force usage of an ELF interpreter even if it is an ELF shared
|
||||
object ! */
|
||||
const char interp[] __attribute__((section(".interp"))) = "/lib/ld-linux.so.2";
|
||||
#endif
|
||||
|
||||
/* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so
|
||||
we allocate a bigger stack. Need a better solution, for example
|
||||
by remapping the process stack directly at the right place */
|
||||
@@ -106,41 +115,39 @@ uint64_t gdt_table[6];
|
||||
|
||||
//#define DEBUG_VM86
|
||||
|
||||
void cpu_loop(struct CPUX86State *env)
|
||||
static inline int is_revectored(int nr, struct target_revectored_struct *bitmap)
|
||||
{
|
||||
int err;
|
||||
uint8_t *pc;
|
||||
target_siginfo_t info;
|
||||
return (tswap32(bitmap->__map[nr >> 5]) >> (nr & 0x1f)) & 1;
|
||||
}
|
||||
|
||||
for(;;) {
|
||||
err = cpu_x86_exec(env);
|
||||
pc = env->seg_cache[R_CS].base + env->eip;
|
||||
switch(err) {
|
||||
case EXCP0D_GPF:
|
||||
if (env->eflags & VM_MASK) {
|
||||
TaskState *ts;
|
||||
int ret;
|
||||
#ifdef DEBUG_VM86
|
||||
printf("VM86 exception %04x:%08x %02x\n",
|
||||
env->segs[R_CS], env->eip, pc[0]);
|
||||
#endif
|
||||
/* VM86 mode */
|
||||
ts = env->opaque;
|
||||
static inline uint8_t *seg_to_linear(unsigned int seg, unsigned int reg)
|
||||
{
|
||||
return (uint8_t *)((seg << 4) + (reg & 0xffff));
|
||||
}
|
||||
|
||||
/* XXX: add all cases */
|
||||
switch(pc[0]) {
|
||||
case 0xcd: /* int */
|
||||
env->eip += 2;
|
||||
ret = TARGET_VM86_INTx | (pc[1] << 8);
|
||||
break;
|
||||
default:
|
||||
/* real VM86 GPF exception */
|
||||
ret = TARGET_VM86_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
static inline void pushw(CPUX86State *env, int val)
|
||||
{
|
||||
env->regs[R_ESP] = (env->regs[R_ESP] & ~0xffff) |
|
||||
((env->regs[R_ESP] - 2) & 0xffff);
|
||||
*(uint16_t *)seg_to_linear(env->segs[R_SS], env->regs[R_ESP]) = val;
|
||||
}
|
||||
|
||||
static inline unsigned int get_vflags(CPUX86State *env)
|
||||
{
|
||||
unsigned int eflags;
|
||||
eflags = env->eflags & ~(VM_MASK | RF_MASK | IF_MASK);
|
||||
if (eflags & VIF_MASK)
|
||||
eflags |= IF_MASK;
|
||||
return eflags;
|
||||
}
|
||||
|
||||
void save_v86_state(CPUX86State *env)
|
||||
{
|
||||
TaskState *ts = env->opaque;
|
||||
#ifdef DEBUG_VM86
|
||||
printf("ret=0x%x\n", ret);
|
||||
printf("save_v86_state\n");
|
||||
#endif
|
||||
|
||||
/* put the VM86 registers in the userspace register structure */
|
||||
ts->target_v86->regs.eax = tswap32(env->regs[R_EAX]);
|
||||
ts->target_v86->regs.ebx = tswap32(env->regs[R_EBX]);
|
||||
@@ -157,8 +164,10 @@ void cpu_loop(struct CPUX86State *env)
|
||||
ts->target_v86->regs.es = tswap16(env->segs[R_ES]);
|
||||
ts->target_v86->regs.fs = tswap16(env->segs[R_FS]);
|
||||
ts->target_v86->regs.gs = tswap16(env->segs[R_GS]);
|
||||
ts->target_v86->regs.eflags = tswap32(env->eflags);
|
||||
|
||||
/* restore 32 bit registers */
|
||||
env->regs[R_EAX] = ts->vm86_saved_regs.eax;
|
||||
env->regs[R_EBX] = ts->vm86_saved_regs.ebx;
|
||||
env->regs[R_ECX] = ts->vm86_saved_regs.ecx;
|
||||
env->regs[R_EDX] = ts->vm86_saved_regs.edx;
|
||||
@@ -175,8 +184,103 @@ void cpu_loop(struct CPUX86State *env)
|
||||
cpu_x86_load_seg(env, R_ES, ts->vm86_saved_regs.es);
|
||||
cpu_x86_load_seg(env, R_FS, ts->vm86_saved_regs.fs);
|
||||
cpu_x86_load_seg(env, R_GS, ts->vm86_saved_regs.gs);
|
||||
}
|
||||
|
||||
env->regs[R_EAX] = ret;
|
||||
/* return from vm86 mode to 32 bit. The vm86() syscall will return
|
||||
'retval' */
|
||||
static inline void return_to_32bit(CPUX86State *env, int retval)
|
||||
{
|
||||
#ifdef DEBUG_VM86
|
||||
printf("return_to_32bit: ret=0x%x\n", retval);
|
||||
#endif
|
||||
save_v86_state(env);
|
||||
env->regs[R_EAX] = retval;
|
||||
}
|
||||
|
||||
/* handle VM86 interrupt (NOTE: the CPU core currently does not
|
||||
support TSS interrupt revectoring, so this code is always executed) */
|
||||
static void do_int(CPUX86State *env, int intno)
|
||||
{
|
||||
TaskState *ts = env->opaque;
|
||||
uint32_t *int_ptr, segoffs;
|
||||
|
||||
if (env->segs[R_CS] == TARGET_BIOSSEG)
|
||||
goto cannot_handle; /* XXX: I am not sure this is really useful */
|
||||
if (is_revectored(intno, &ts->target_v86->int_revectored))
|
||||
goto cannot_handle;
|
||||
if (intno == 0x21 && is_revectored((env->regs[R_EAX] >> 8) & 0xff,
|
||||
&ts->target_v86->int21_revectored))
|
||||
goto cannot_handle;
|
||||
int_ptr = (uint32_t *)(intno << 2);
|
||||
segoffs = tswap32(*int_ptr);
|
||||
if ((segoffs >> 16) == TARGET_BIOSSEG)
|
||||
goto cannot_handle;
|
||||
#ifdef DEBUG_VM86
|
||||
printf("VM86: emulating int 0x%x. CS:IP=%04x:%04x\n",
|
||||
intno, segoffs >> 16, segoffs & 0xffff);
|
||||
#endif
|
||||
/* save old state */
|
||||
pushw(env, get_vflags(env));
|
||||
pushw(env, env->segs[R_CS]);
|
||||
pushw(env, env->eip);
|
||||
/* goto interrupt handler */
|
||||
env->eip = segoffs & 0xffff;
|
||||
cpu_x86_load_seg(env, R_CS, segoffs >> 16);
|
||||
env->eflags &= ~(VIF_MASK | TF_MASK);
|
||||
return;
|
||||
cannot_handle:
|
||||
#ifdef DEBUG_VM86
|
||||
printf("VM86: return to 32 bits int 0x%x\n", intno);
|
||||
#endif
|
||||
return_to_32bit(env, TARGET_VM86_INTx | (intno << 8));
|
||||
}
|
||||
|
||||
void cpu_loop(struct CPUX86State *env)
|
||||
{
|
||||
int trapnr;
|
||||
uint8_t *pc;
|
||||
target_siginfo_t info;
|
||||
|
||||
for(;;) {
|
||||
trapnr = cpu_x86_exec(env);
|
||||
pc = env->seg_cache[R_CS].base + env->eip;
|
||||
switch(trapnr) {
|
||||
case EXCP0D_GPF:
|
||||
if (env->eflags & VM_MASK) {
|
||||
#ifdef DEBUG_VM86
|
||||
printf("VM86 exception %04x:%08x %02x %02x\n",
|
||||
env->segs[R_CS], env->eip, pc[0], pc[1]);
|
||||
#endif
|
||||
/* VM86 mode */
|
||||
switch(pc[0]) {
|
||||
case 0xcd: /* int */
|
||||
env->eip += 2;
|
||||
do_int(env, pc[1]);
|
||||
break;
|
||||
case 0x66:
|
||||
switch(pc[1]) {
|
||||
case 0xfb: /* sti */
|
||||
case 0x9d: /* popf */
|
||||
case 0xcf: /* iret */
|
||||
env->eip += 2;
|
||||
return_to_32bit(env, TARGET_VM86_STI);
|
||||
break;
|
||||
default:
|
||||
goto vm86_gpf;
|
||||
}
|
||||
break;
|
||||
case 0xfb: /* sti */
|
||||
case 0x9d: /* popf */
|
||||
case 0xcf: /* iret */
|
||||
env->eip++;
|
||||
return_to_32bit(env, TARGET_VM86_STI);
|
||||
break;
|
||||
default:
|
||||
vm86_gpf:
|
||||
/* real VM86 GPF exception */
|
||||
return_to_32bit(env, TARGET_VM86_UNKNOWN);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (pc[0] == 0xcd && pc[1] == 0x80) {
|
||||
/* syscall */
|
||||
@@ -200,20 +304,28 @@ void cpu_loop(struct CPUX86State *env)
|
||||
}
|
||||
break;
|
||||
case EXCP00_DIVZ:
|
||||
if (env->eflags & VM_MASK) {
|
||||
do_int(env, trapnr);
|
||||
} else {
|
||||
/* division by zero */
|
||||
info.si_signo = SIGFPE;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_FPE_INTDIV;
|
||||
info._sifields._sigfault._addr = env->eip;
|
||||
queue_signal(info.si_signo, &info);
|
||||
}
|
||||
break;
|
||||
case EXCP04_INTO:
|
||||
case EXCP05_BOUND:
|
||||
if (env->eflags & VM_MASK) {
|
||||
do_int(env, trapnr);
|
||||
} else {
|
||||
info.si_signo = SIGSEGV;
|
||||
info.si_errno = 0;
|
||||
info.si_code = 0;
|
||||
info._sifields._sigfault._addr = 0;
|
||||
queue_signal(info.si_signo, &info);
|
||||
}
|
||||
break;
|
||||
case EXCP06_ILLOP:
|
||||
info.si_signo = SIGILL;
|
||||
@@ -226,8 +338,8 @@ void cpu_loop(struct CPUX86State *env)
|
||||
/* just indicate that signals should be handled asap */
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "0x%08lx: Unknown exception CPU %d, aborting\n",
|
||||
(long)pc, err);
|
||||
fprintf(stderr, "qemu: 0x%08lx: unhandled CPU exception 0x%x - aborting\n",
|
||||
(long)pc, trapnr);
|
||||
abort();
|
||||
}
|
||||
process_pending_signals(env);
|
||||
@@ -267,6 +379,13 @@ int main(int argc, char **argv)
|
||||
|
||||
if (argc <= 1)
|
||||
usage();
|
||||
|
||||
/* Set personality to X86_LINUX. May fail on unpatched kernels:
|
||||
if so, they need to have munged paths themselves (eg. chroot,
|
||||
hacked ld.so, whatever). */
|
||||
if (personality(0x11) >= 0)
|
||||
interp_prefix = "";
|
||||
|
||||
loglevel = 0;
|
||||
optind = 1;
|
||||
for(;;) {
|
||||
|
@@ -74,5 +74,6 @@ void cpu_loop(CPUX86State *env);
|
||||
void process_pending_signals(void *cpu_env);
|
||||
void signal_init(void);
|
||||
int queue_signal(int sig, target_siginfo_t *info);
|
||||
void save_v86_state(CPUX86State *env);
|
||||
|
||||
#endif
|
||||
|
@@ -198,7 +198,7 @@ void __attribute((noreturn)) force_sig(int sig)
|
||||
{
|
||||
int host_sig;
|
||||
host_sig = target_to_host_signal(sig);
|
||||
fprintf(stderr, "gemu: uncaught target signal %d (%s) - exiting\n",
|
||||
fprintf(stderr, "qemu: uncaught target signal %d (%s) - exiting\n",
|
||||
sig, strsignal(host_sig));
|
||||
#if 1
|
||||
_exit(-host_sig);
|
||||
@@ -223,7 +223,7 @@ int queue_signal(int sig, target_siginfo_t *info)
|
||||
target_ulong handler;
|
||||
|
||||
#if defined(DEBUG_SIGNAL)
|
||||
fprintf(stderr, "queue_sigal: sig=%d\n",
|
||||
fprintf(stderr, "queue_signal: sig=%d\n",
|
||||
sig);
|
||||
#endif
|
||||
k = &sigact_table[sig - 1];
|
||||
@@ -317,7 +317,7 @@ static void host_signal_handler(int host_signum, siginfo_t *info,
|
||||
if (sig < 1 || sig > TARGET_NSIG)
|
||||
return;
|
||||
#if defined(DEBUG_SIGNAL)
|
||||
fprintf(stderr, "gemu: got signal %d\n", sig);
|
||||
fprintf(stderr, "qemu: got signal %d\n", sig);
|
||||
dump_regs(puc);
|
||||
#endif
|
||||
host_to_target_siginfo_noswap(&tinfo, info);
|
||||
@@ -538,7 +538,6 @@ setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate,
|
||||
/* non-iBCS2 extensions.. */
|
||||
err |= __put_user(mask, &sc->oldmask);
|
||||
err |= __put_user(/*current->thread.cr2*/ 0, &sc->cr2);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -859,7 +858,7 @@ void process_pending_signals(void *cpu_env)
|
||||
|
||||
handle_signal:
|
||||
#ifdef DEBUG_SIGNAL
|
||||
fprintf(stderr, "gemu: process signal %d\n", sig);
|
||||
fprintf(stderr, "qemu: process signal %d\n", sig);
|
||||
#endif
|
||||
/* dequeue signal */
|
||||
q = k->first;
|
||||
@@ -893,6 +892,14 @@ void process_pending_signals(void *cpu_env)
|
||||
end of the signal execution (see do_sigreturn) */
|
||||
host_to_target_sigset(&target_old_set, &old_set);
|
||||
|
||||
/* if the CPU is in VM86 mode, we restore the 32 bit values */
|
||||
#ifdef TARGET_I386
|
||||
{
|
||||
CPUX86State *env = cpu_env;
|
||||
if (env->eflags & VM_MASK)
|
||||
save_v86_state(env);
|
||||
}
|
||||
#endif
|
||||
/* prepare the stack frame of the virtual CPU */
|
||||
if (k->sa.sa_flags & TARGET_SA_SIGINFO)
|
||||
setup_rt_frame(sig, k, &q->info, &target_old_set, cpu_env);
|
||||
|
@@ -40,6 +40,7 @@
|
||||
#include <sys/socket.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/poll.h>
|
||||
#include <sys/times.h>
|
||||
//#include <sys/user.h>
|
||||
#include <netinet/tcp.h>
|
||||
|
||||
@@ -84,6 +85,10 @@ long do_rt_sigreturn(CPUX86State *env);
|
||||
#define __NR_sys_getdents64 __NR_getdents64
|
||||
#define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
|
||||
|
||||
#ifdef __alpha__
|
||||
#define __NR__llseek __NR_lseek
|
||||
#endif
|
||||
|
||||
#ifdef __NR_gettid
|
||||
_syscall0(int, gettid)
|
||||
#else
|
||||
@@ -1077,7 +1082,6 @@ int do_vm86(CPUX86State *env, long subfunction,
|
||||
}
|
||||
|
||||
ts->target_v86 = target_v86;
|
||||
|
||||
/* save current CPU regs */
|
||||
ts->vm86_saved_regs.eax = 0; /* default vm86 syscall return code */
|
||||
ts->vm86_saved_regs.ebx = env->regs[R_EBX];
|
||||
@@ -1239,22 +1243,27 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
|
||||
case TARGET_NR_execve:
|
||||
{
|
||||
char **argp, **envp;
|
||||
int argc = 0, envc = 0;
|
||||
int argc, envc;
|
||||
uint32_t *p;
|
||||
char **q;
|
||||
|
||||
argc = 0;
|
||||
for (p = (void *)arg2; *p; p++)
|
||||
argc++;
|
||||
envc = 0;
|
||||
for (p = (void *)arg3; *p; p++)
|
||||
envc++;
|
||||
|
||||
argp = alloca(argc * sizeof(void *));
|
||||
envp = alloca(envc * sizeof(void *));
|
||||
argp = alloca((argc + 1) * sizeof(void *));
|
||||
envp = alloca((envc + 1) * sizeof(void *));
|
||||
|
||||
for (p = (void *)arg2, q = argp; *p; p++, q++)
|
||||
*q = (void *)tswap32(*p);
|
||||
*q = NULL;
|
||||
|
||||
for (p = (void *)arg3, q = envp; *p; p++, q++)
|
||||
*q = (void *)tswap32(*p);
|
||||
*q = NULL;
|
||||
|
||||
ret = get_errno(execve((const char *)arg1, argp, envp));
|
||||
}
|
||||
@@ -1363,7 +1372,18 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
|
||||
}
|
||||
break;
|
||||
case TARGET_NR_times:
|
||||
goto unimplemented;
|
||||
{
|
||||
struct target_tms *tmsp = (void *)arg1;
|
||||
struct tms tms;
|
||||
ret = get_errno(times(&tms));
|
||||
if (tmsp) {
|
||||
tmsp->tms_utime = tswapl(tms.tms_utime);
|
||||
tmsp->tms_stime = tswapl(tms.tms_stime);
|
||||
tmsp->tms_cutime = tswapl(tms.tms_cutime);
|
||||
tmsp->tms_cstime = tswapl(tms.tms_cstime);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TARGET_NR_prof:
|
||||
goto unimplemented;
|
||||
case TARGET_NR_setgid:
|
||||
@@ -1837,7 +1857,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
|
||||
struct target_stat *target_st = (void *)arg2;
|
||||
target_st->st_dev = tswap16(st.st_dev);
|
||||
target_st->st_ino = tswapl(st.st_ino);
|
||||
target_st->st_mode = tswap16(st.st_mode);
|
||||
target_st->st_mode = tswap32(st.st_mode);
|
||||
target_st->st_nlink = tswap16(st.st_nlink);
|
||||
target_st->st_uid = tswap16(st.st_uid);
|
||||
target_st->st_gid = tswap16(st.st_gid);
|
||||
@@ -2228,7 +2248,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
|
||||
struct target_stat64 *target_st = (void *)arg2;
|
||||
target_st->st_dev = tswap16(st.st_dev);
|
||||
target_st->st_ino = tswapl(st.st_ino);
|
||||
target_st->st_mode = tswap16(st.st_mode);
|
||||
target_st->st_mode = tswap32(st.st_mode);
|
||||
target_st->st_nlink = tswap16(st.st_nlink);
|
||||
target_st->st_uid = tswap16(st.st_uid);
|
||||
target_st->st_gid = tswap16(st.st_gid);
|
||||
|
@@ -39,6 +39,15 @@ struct target_itimerval {
|
||||
struct target_timeval it_value;
|
||||
};
|
||||
|
||||
typedef target_long target_clock_t;
|
||||
|
||||
struct target_tms {
|
||||
target_clock_t tms_utime;
|
||||
target_clock_t tms_stime;
|
||||
target_clock_t tms_cutime;
|
||||
target_clock_t tms_cstime;
|
||||
};
|
||||
|
||||
struct target_iovec {
|
||||
target_long iov_base; /* Starting address */
|
||||
target_long iov_len; /* Number of bytes */
|
||||
|
143
op-i386.c
143
op-i386.c
@@ -412,6 +412,22 @@ void OPPROTO op_idivw_AX_T0(void)
|
||||
EDX = (EDX & 0xffff0000) | r;
|
||||
}
|
||||
|
||||
#ifdef BUGGY_GCC_DIV64
|
||||
/* gcc 2.95.4 on PowerPC does not seem to like using __udivdi3, so we
|
||||
call it from another function */
|
||||
uint32_t div64(uint32_t *q_ptr, uint64_t num, uint32_t den)
|
||||
{
|
||||
*q_ptr = num / den;
|
||||
return num % den;
|
||||
}
|
||||
|
||||
int32_t idiv64(int32_t *q_ptr, int64_t num, int32_t den)
|
||||
{
|
||||
*q_ptr = num / den;
|
||||
return num % den;
|
||||
}
|
||||
#endif
|
||||
|
||||
void OPPROTO op_divl_EAX_T0(void)
|
||||
{
|
||||
unsigned int den, q, r;
|
||||
@@ -421,8 +437,12 @@ void OPPROTO op_divl_EAX_T0(void)
|
||||
den = T0;
|
||||
if (den == 0)
|
||||
raise_exception(EXCP00_DIVZ);
|
||||
#ifdef BUGGY_GCC_DIV64
|
||||
r = div64(&q, num, den);
|
||||
#else
|
||||
q = (num / den);
|
||||
r = (num % den);
|
||||
#endif
|
||||
EAX = q;
|
||||
EDX = r;
|
||||
}
|
||||
@@ -436,8 +456,12 @@ void OPPROTO op_idivl_EAX_T0(void)
|
||||
den = T0;
|
||||
if (den == 0)
|
||||
raise_exception(EXCP00_DIVZ);
|
||||
#ifdef BUGGY_GCC_DIV64
|
||||
r = idiv64(&q, num, den);
|
||||
#else
|
||||
q = (num / den);
|
||||
r = (num % den);
|
||||
#endif
|
||||
EAX = q;
|
||||
EDX = r;
|
||||
}
|
||||
@@ -611,6 +635,35 @@ void OPPROTO op_into(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX: add IOPL/CPL tests */
|
||||
void OPPROTO op_cli(void)
|
||||
{
|
||||
raise_exception(EXCP0D_GPF);
|
||||
}
|
||||
|
||||
/* XXX: add IOPL/CPL tests */
|
||||
void OPPROTO op_sti(void)
|
||||
{
|
||||
raise_exception(EXCP0D_GPF);
|
||||
}
|
||||
|
||||
/* vm86plus instructions */
|
||||
|
||||
void OPPROTO op_cli_vm(void)
|
||||
{
|
||||
env->eflags &= ~VIF_MASK;
|
||||
}
|
||||
|
||||
void OPPROTO op_sti_vm(void)
|
||||
{
|
||||
env->eflags |= VIF_MASK;
|
||||
if (env->eflags & VIP_MASK) {
|
||||
EIP = PARAM1;
|
||||
raise_exception(EXCP0D_GPF);
|
||||
}
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
void OPPROTO op_boundw(void)
|
||||
{
|
||||
int low, high, v;
|
||||
@@ -1234,7 +1287,8 @@ void OPPROTO op_set_cc_op(void)
|
||||
CC_OP = PARAM1;
|
||||
}
|
||||
|
||||
#define FL_UPDATE_MASK (TF_MASK | AC_MASK | ID_MASK)
|
||||
#define FL_UPDATE_MASK32 (TF_MASK | AC_MASK | ID_MASK)
|
||||
#define FL_UPDATE_MASK16 (TF_MASK)
|
||||
|
||||
void OPPROTO op_movl_eflags_T0(void)
|
||||
{
|
||||
@@ -1243,7 +1297,56 @@ void OPPROTO op_movl_eflags_T0(void)
|
||||
CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
|
||||
DF = 1 - (2 * ((eflags >> 10) & 1));
|
||||
/* we also update some system flags as in user mode */
|
||||
env->eflags = (env->eflags & ~FL_UPDATE_MASK) | (eflags & FL_UPDATE_MASK);
|
||||
env->eflags = (env->eflags & ~FL_UPDATE_MASK32) | (eflags & FL_UPDATE_MASK32);
|
||||
}
|
||||
|
||||
void OPPROTO op_movw_eflags_T0(void)
|
||||
{
|
||||
int eflags;
|
||||
eflags = T0;
|
||||
CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
|
||||
DF = 1 - (2 * ((eflags >> 10) & 1));
|
||||
/* we also update some system flags as in user mode */
|
||||
env->eflags = (env->eflags & ~FL_UPDATE_MASK16) | (eflags & FL_UPDATE_MASK16);
|
||||
}
|
||||
|
||||
/* vm86 version */
|
||||
void OPPROTO op_movw_eflags_T0_vm(void)
|
||||
{
|
||||
int eflags;
|
||||
eflags = T0;
|
||||
CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
|
||||
DF = 1 - (2 * ((eflags >> 10) & 1));
|
||||
/* we also update some system flags as in user mode */
|
||||
env->eflags = (env->eflags & ~(FL_UPDATE_MASK16 | VIF_MASK)) |
|
||||
(eflags & FL_UPDATE_MASK16);
|
||||
if (eflags & IF_MASK) {
|
||||
env->eflags |= VIF_MASK;
|
||||
if (env->eflags & VIP_MASK) {
|
||||
EIP = PARAM1;
|
||||
raise_exception(EXCP0D_GPF);
|
||||
}
|
||||
}
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
void OPPROTO op_movl_eflags_T0_vm(void)
|
||||
{
|
||||
int eflags;
|
||||
eflags = T0;
|
||||
CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
|
||||
DF = 1 - (2 * ((eflags >> 10) & 1));
|
||||
/* we also update some system flags as in user mode */
|
||||
env->eflags = (env->eflags & ~(FL_UPDATE_MASK32 | VIF_MASK)) |
|
||||
(eflags & FL_UPDATE_MASK32);
|
||||
if (eflags & IF_MASK) {
|
||||
env->eflags |= VIF_MASK;
|
||||
if (env->eflags & VIP_MASK) {
|
||||
EIP = PARAM1;
|
||||
raise_exception(EXCP0D_GPF);
|
||||
}
|
||||
}
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
/* XXX: compute only O flag */
|
||||
@@ -1263,6 +1366,18 @@ void OPPROTO op_movl_T0_eflags(void)
|
||||
T0 = eflags;
|
||||
}
|
||||
|
||||
/* vm86 version */
|
||||
void OPPROTO op_movl_T0_eflags_vm(void)
|
||||
{
|
||||
int eflags;
|
||||
eflags = cc_table[CC_OP].compute_all();
|
||||
eflags |= (DF & DF_MASK);
|
||||
eflags |= env->eflags & ~(VM_MASK | RF_MASK | IF_MASK);
|
||||
if (env->eflags & VIF_MASK)
|
||||
eflags |= IF_MASK;
|
||||
T0 = eflags;
|
||||
}
|
||||
|
||||
void OPPROTO op_cld(void)
|
||||
{
|
||||
DF = 1;
|
||||
@@ -1377,7 +1492,9 @@ CCTable cc_table[CC_OP_NB] = {
|
||||
[CC_OP_SARL] = { compute_all_sarl, compute_c_shll },
|
||||
};
|
||||
|
||||
/* floating point support */
|
||||
/* floating point support. Some of the code for complicated x87
|
||||
functions comes from the LGPL'ed x86 emulator found in the Willows
|
||||
TWIN windows emulator. */
|
||||
|
||||
#ifdef USE_X86LDOUBLE
|
||||
/* use long double functions */
|
||||
@@ -1410,6 +1527,26 @@ extern CPU86_LDouble floor(CPU86_LDouble x);
|
||||
extern CPU86_LDouble ceil(CPU86_LDouble x);
|
||||
extern CPU86_LDouble rint(CPU86_LDouble x);
|
||||
|
||||
#if defined(__powerpc__)
|
||||
extern CPU86_LDouble copysign(CPU86_LDouble, CPU86_LDouble);
|
||||
|
||||
/* correct (but slow) PowerPC rint() (glibc version is incorrect) */
|
||||
double qemu_rint(double x)
|
||||
{
|
||||
double y = 4503599627370496.0;
|
||||
if (fabs(x) >= y)
|
||||
return x;
|
||||
if (x < 0)
|
||||
y = -y;
|
||||
y = (x + y) - y;
|
||||
if (y == 0.0)
|
||||
y = copysign(y, x);
|
||||
return y;
|
||||
}
|
||||
|
||||
#define rint qemu_rint
|
||||
#endif
|
||||
|
||||
#define RC_MASK 0xc00
|
||||
#define RC_NEAR 0x000
|
||||
#define RC_DOWN 0x400
|
||||
|
@@ -232,6 +232,10 @@ DEF(jmp_im, 1)
|
||||
DEF(int_im, 1)
|
||||
DEF(int3, 1)
|
||||
DEF(into, 0)
|
||||
DEF(cli, 0)
|
||||
DEF(sti, 0)
|
||||
DEF(cli_vm, 0)
|
||||
DEF(sti_vm, 1)
|
||||
DEF(boundw, 0)
|
||||
DEF(boundl, 0)
|
||||
DEF(cmpxchg8b, 0)
|
||||
@@ -551,8 +555,12 @@ DEF(setle_T0_cc, 0)
|
||||
DEF(xor_T0_1, 0)
|
||||
DEF(set_cc_op, 1)
|
||||
DEF(movl_eflags_T0, 0)
|
||||
DEF(movw_eflags_T0, 0)
|
||||
DEF(movw_eflags_T0_vm, 1)
|
||||
DEF(movl_eflags_T0_vm, 1)
|
||||
DEF(movb_eflags_T0, 0)
|
||||
DEF(movl_T0_eflags, 0)
|
||||
DEF(movl_T0_eflags_vm, 0)
|
||||
DEF(cld, 0)
|
||||
DEF(std, 0)
|
||||
DEF(clc, 0)
|
||||
|
@@ -609,6 +609,7 @@ void OPPROTO glue(glue(op_shld, SUFFIX), _T0_T1_ECX_cc)(void)
|
||||
CC_DST = T0;
|
||||
CC_OP = CC_OP_SARB + SHIFT;
|
||||
}
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
void OPPROTO glue(glue(op_shrd, SUFFIX), _T0_T1_im_cc)(void)
|
||||
@@ -643,6 +644,7 @@ void OPPROTO glue(glue(op_shrd, SUFFIX), _T0_T1_ECX_cc)(void)
|
||||
CC_DST = T0;
|
||||
CC_OP = CC_OP_SARB + SHIFT;
|
||||
}
|
||||
FORCE_RET();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -670,6 +672,7 @@ void OPPROTO glue(glue(op_shld, SUFFIX), _T0_T1_ECX_cc)(void)
|
||||
CC_DST = T0;
|
||||
CC_OP = CC_OP_SHLB + SHIFT;
|
||||
}
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
void OPPROTO glue(glue(op_shrd, SUFFIX), _T0_T1_im_cc)(void)
|
||||
@@ -696,6 +699,7 @@ void OPPROTO glue(glue(op_shrd, SUFFIX), _T0_T1_ECX_cc)(void)
|
||||
CC_DST = T0;
|
||||
CC_OP = CC_OP_SARB + SHIFT;
|
||||
}
|
||||
FORCE_RET();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@@ -427,8 +427,8 @@ typedef struct target_siginfo {
|
||||
pid_t _pid; /* which child */
|
||||
uid_t _uid; /* sender's uid */
|
||||
int _status; /* exit code */
|
||||
clock_t _utime;
|
||||
clock_t _stime;
|
||||
target_clock_t _utime;
|
||||
target_clock_t _stime;
|
||||
} _sigchld;
|
||||
|
||||
/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
|
||||
@@ -755,6 +755,11 @@ struct target_modify_ldt_ldt_s {
|
||||
unsigned int flags;
|
||||
};
|
||||
|
||||
|
||||
/* vm86 defines */
|
||||
|
||||
#define TARGET_BIOSSEG 0x0f000
|
||||
|
||||
#define TARGET_VM86_SIGNAL 0 /* return due to signal */
|
||||
#define TARGET_VM86_UNKNOWN 1 /* unhandled GP fault - IO-instruction or similar */
|
||||
#define TARGET_VM86_INTx 2 /* int3/int x instruction (ARG = x) */
|
||||
@@ -1060,3 +1065,5 @@ union target_semun {
|
||||
|
||||
#define TARGET_VFAT_IOCTL_READDIR_BOTH 0x82187201
|
||||
#define TARGET_VFAT_IOCTL_READDIR_SHORT 0x82187202
|
||||
|
||||
#define TARGET_SIOCATMARK 0x8905
|
||||
|
@@ -28,7 +28,7 @@ testthread: testthread.c
|
||||
# i386 emulation test (test various opcodes) */
|
||||
test-i386: test-i386.c test-i386-code16.S \
|
||||
test-i386.h test-i386-shift.h test-i386-muldiv.h
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ test-i386.c test-i386-code16.S -lm
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -static -o $@ test-i386.c test-i386-code16.S -lm
|
||||
|
||||
test: test-i386
|
||||
ifeq ($(ARCH),i386)
|
||||
|
188
tests/runcom.c
Normal file
188
tests/runcom.c
Normal file
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* Simple example of use of vm86: launch a basic .com DOS executable
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <linux/unistd.h>
|
||||
#include <asm/vm86.h>
|
||||
|
||||
//#define SIGTEST
|
||||
|
||||
_syscall2(int, vm86, int, func, struct vm86plus_struct *, v86)
|
||||
|
||||
#define COM_BASE_ADDR 0x10100
|
||||
|
||||
void usage(void)
|
||||
{
|
||||
printf("runcom version 0.1 (c) 2003 Fabrice Bellard\n"
|
||||
"usage: runcom file.com\n"
|
||||
"VM86 Run simple .com DOS executables (linux vm86 test mode)\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static inline void set_bit(uint8_t *a, unsigned int bit)
|
||||
{
|
||||
a[bit / 8] |= (1 << (bit % 8));
|
||||
}
|
||||
|
||||
static inline uint8_t *seg_to_linear(unsigned int seg, unsigned int reg)
|
||||
{
|
||||
return (uint8_t *)((seg << 4) + (reg & 0xffff));
|
||||
}
|
||||
|
||||
static inline void pushw(struct vm86_regs *r, int val)
|
||||
{
|
||||
r->esp = (r->esp & ~0xffff) | ((r->esp - 2) & 0xffff);
|
||||
*(uint16_t *)seg_to_linear(r->ss, r->esp) = val;
|
||||
}
|
||||
|
||||
void dump_regs(struct vm86_regs *r)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"EAX=%08lx EBX=%08lx ECX=%08lx EDX=%08lx\n"
|
||||
"ESI=%08lx EDI=%08lx EBP=%08lx ESP=%08lx\n"
|
||||
"EIP=%08lx EFL=%08lx\n"
|
||||
"CS=%04x DS=%04x ES=%04x SS=%04x FS=%04x GS=%04x\n",
|
||||
r->eax, r->ebx, r->ecx, r->edx, r->esi, r->edi, r->ebp, r->esp,
|
||||
r->eip, r->eflags,
|
||||
r->cs, r->ds, r->es, r->ss, r->fs, r->gs);
|
||||
}
|
||||
|
||||
#ifdef SIGTEST
|
||||
void alarm_handler(int sig)
|
||||
{
|
||||
fprintf(stderr, "alarm signal=%d\n", sig);
|
||||
alarm(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
uint8_t *vm86_mem;
|
||||
const char *filename;
|
||||
int fd, ret, seg;
|
||||
struct vm86plus_struct ctx;
|
||||
struct vm86_regs *r;
|
||||
|
||||
if (argc != 2)
|
||||
usage();
|
||||
filename = argv[1];
|
||||
|
||||
vm86_mem = mmap((void *)0x00000000, 0x110000,
|
||||
PROT_WRITE | PROT_READ | PROT_EXEC,
|
||||
MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0);
|
||||
if (vm86_mem == MAP_FAILED) {
|
||||
perror("mmap");
|
||||
exit(1);
|
||||
}
|
||||
#ifdef SIGTEST
|
||||
{
|
||||
struct sigaction act;
|
||||
|
||||
act.sa_handler = alarm_handler;
|
||||
sigemptyset(&act.sa_mask);
|
||||
act.sa_flags = 0;
|
||||
sigaction(SIGALRM, &act, NULL);
|
||||
alarm(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* load the MSDOS .com executable */
|
||||
fd = open(filename, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
perror(filename);
|
||||
exit(1);
|
||||
}
|
||||
ret = read(fd, vm86_mem + COM_BASE_ADDR, 65536 - 256);
|
||||
if (ret < 0) {
|
||||
perror("read");
|
||||
exit(1);
|
||||
}
|
||||
close(fd);
|
||||
|
||||
memset(&ctx, 0, sizeof(ctx));
|
||||
/* init basic registers */
|
||||
r = &ctx.regs;
|
||||
r->eip = 0x100;
|
||||
r->esp = 0xfffe;
|
||||
seg = (COM_BASE_ADDR - 0x100) >> 4;
|
||||
r->cs = seg;
|
||||
r->ss = seg;
|
||||
r->ds = seg;
|
||||
r->es = seg;
|
||||
r->fs = seg;
|
||||
r->gs = seg;
|
||||
r->eflags = (IF_MASK | IOPL_MASK);
|
||||
|
||||
/* put return code */
|
||||
set_bit((uint8_t *)&ctx.int_revectored, 0x21);
|
||||
*seg_to_linear(r->cs, 0) = 0xb4; /* mov ah, $0 */
|
||||
*seg_to_linear(r->cs, 1) = 0x00;
|
||||
*seg_to_linear(r->cs, 2) = 0xcd; /* int $0x21 */
|
||||
*seg_to_linear(r->cs, 3) = 0x21;
|
||||
pushw(&ctx.regs, 0x0000);
|
||||
|
||||
/* the value of these registers seem to be assumed by pi_10.com */
|
||||
r->esi = 0x100;
|
||||
r->ecx = 0xff;
|
||||
r->ebp = 0x0900;
|
||||
r->edi = 0xfffe;
|
||||
|
||||
for(;;) {
|
||||
ret = vm86(VM86_ENTER, &ctx);
|
||||
switch(VM86_TYPE(ret)) {
|
||||
case VM86_INTx:
|
||||
{
|
||||
int int_num, ah;
|
||||
|
||||
int_num = VM86_ARG(ret);
|
||||
if (int_num != 0x21)
|
||||
goto unknown_int;
|
||||
ah = (r->eax >> 8) & 0xff;
|
||||
switch(ah) {
|
||||
case 0x00: /* exit */
|
||||
exit(0);
|
||||
case 0x02: /* write char */
|
||||
{
|
||||
uint8_t c = r->edx;
|
||||
write(1, &c, 1);
|
||||
}
|
||||
break;
|
||||
case 0x09: /* write string */
|
||||
{
|
||||
uint8_t c;
|
||||
for(;;) {
|
||||
c = *seg_to_linear(r->ds, r->edx);
|
||||
if (c == '$')
|
||||
break;
|
||||
write(1, &c, 1);
|
||||
}
|
||||
r->eax = (r->eax & ~0xff) | '$';
|
||||
}
|
||||
break;
|
||||
default:
|
||||
unknown_int:
|
||||
fprintf(stderr, "unsupported int 0x%02x\n", int_num);
|
||||
dump_regs(&ctx.regs);
|
||||
// exit(1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case VM86_SIGNAL:
|
||||
/* a signal came, we just ignore that */
|
||||
break;
|
||||
case VM86_STI:
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "unhandled vm86 return code (0x%x)\n", ret);
|
||||
dump_regs(&ctx.regs);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
2
thunk.c
2
thunk.c
@@ -218,7 +218,7 @@ const argtype *thunk_convert(void *dst, const void *src,
|
||||
case TYPE_LONG:
|
||||
case TYPE_ULONG:
|
||||
case TYPE_PTRVOID:
|
||||
if (target_to_host) {
|
||||
if (to_host) {
|
||||
*(uint64_t *)dst = tswap32(*(uint32_t *)src);
|
||||
} else {
|
||||
*(uint32_t *)dst = tswap32(*(uint64_t *)src & 0xffffffff);
|
||||
|
@@ -1919,7 +1919,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
|
||||
break;
|
||||
case 0x1a0: /* push fs */
|
||||
case 0x1a8: /* push gs */
|
||||
gen_op_movl_T0_seg(((b >> 3) & 7) + R_FS);
|
||||
gen_op_movl_T0_seg((b >> 3) & 7);
|
||||
gen_push_T0(s);
|
||||
break;
|
||||
case 0x07: /* pop es */
|
||||
@@ -1932,7 +1932,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
|
||||
case 0x1a1: /* pop fs */
|
||||
case 0x1a9: /* pop gs */
|
||||
gen_pop_T0(s);
|
||||
gen_movl_seg_T0(s, ((b >> 3) & 7) + R_FS);
|
||||
gen_movl_seg_T0(s, (b >> 3) & 7);
|
||||
gen_pop_update(s);
|
||||
break;
|
||||
|
||||
@@ -2833,6 +2833,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
|
||||
s->is_jmp = 1;
|
||||
break;
|
||||
case 0xca: /* lret im */
|
||||
/* XXX: not restartable */
|
||||
val = ldsw(s->pc);
|
||||
s->pc += 2;
|
||||
/* pop offset */
|
||||
@@ -2853,6 +2854,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
|
||||
s->is_jmp = 1;
|
||||
break;
|
||||
case 0xcb: /* lret */
|
||||
/* XXX: not restartable */
|
||||
/* pop offset */
|
||||
gen_pop_T0(s);
|
||||
if (s->dflag == 0)
|
||||
@@ -2865,6 +2867,35 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
|
||||
gen_pop_update(s);
|
||||
s->is_jmp = 1;
|
||||
break;
|
||||
case 0xcf: /* iret */
|
||||
/* XXX: not restartable */
|
||||
/* pop offset */
|
||||
gen_pop_T0(s);
|
||||
if (s->dflag == 0)
|
||||
gen_op_andl_T0_ffff();
|
||||
gen_op_jmp_T0();
|
||||
gen_pop_update(s);
|
||||
/* pop selector */
|
||||
gen_pop_T0(s);
|
||||
gen_movl_seg_T0(s, R_CS);
|
||||
gen_pop_update(s);
|
||||
/* pop eflags */
|
||||
gen_pop_T0(s);
|
||||
if (s->dflag) {
|
||||
if (s->vm86)
|
||||
gen_op_movl_eflags_T0_vm(pc_start - s->cs_base);
|
||||
else
|
||||
gen_op_movl_eflags_T0();
|
||||
} else {
|
||||
if (s->vm86)
|
||||
gen_op_movw_eflags_T0_vm(pc_start - s->cs_base);
|
||||
else
|
||||
gen_op_movw_eflags_T0();
|
||||
}
|
||||
gen_pop_update(s);
|
||||
s->cc_op = CC_OP_EFLAGS;
|
||||
s->is_jmp = 1;
|
||||
break;
|
||||
case 0xe8: /* call im */
|
||||
{
|
||||
unsigned int next_eip;
|
||||
@@ -2978,12 +3009,25 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
|
||||
case 0x9c: /* pushf */
|
||||
if (s->cc_op != CC_OP_DYNAMIC)
|
||||
gen_op_set_cc_op(s->cc_op);
|
||||
if (s->vm86)
|
||||
gen_op_movl_T0_eflags_vm();
|
||||
else
|
||||
gen_op_movl_T0_eflags();
|
||||
gen_push_T0(s);
|
||||
break;
|
||||
case 0x9d: /* popf */
|
||||
gen_pop_T0(s);
|
||||
if (s->dflag) {
|
||||
if (s->vm86)
|
||||
gen_op_movl_eflags_T0_vm(pc_start - s->cs_base);
|
||||
else
|
||||
gen_op_movl_eflags_T0();
|
||||
} else {
|
||||
if (s->vm86)
|
||||
gen_op_movw_eflags_T0_vm(pc_start - s->cs_base);
|
||||
else
|
||||
gen_op_movw_eflags_T0();
|
||||
}
|
||||
gen_pop_update(s);
|
||||
s->cc_op = CC_OP_EFLAGS;
|
||||
break;
|
||||
@@ -3159,6 +3203,18 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
|
||||
gen_op_set_cc_op(s->cc_op);
|
||||
gen_op_into();
|
||||
break;
|
||||
case 0xfa: /* cli */
|
||||
if (s->vm86)
|
||||
gen_op_cli_vm();
|
||||
else
|
||||
gen_op_cli();
|
||||
break;
|
||||
case 0xfb: /* sti */
|
||||
if (s->vm86)
|
||||
gen_op_sti_vm(pc_start - s->cs_base);
|
||||
else
|
||||
gen_op_sti();
|
||||
break;
|
||||
case 0x62: /* bound */
|
||||
ot = dflag ? OT_LONG : OT_WORD;
|
||||
modrm = ldub(s->pc++);
|
||||
@@ -3308,6 +3364,7 @@ static uint16_t opc_read_flags[NB_OPS] = {
|
||||
[INDEX_op_setle_T0_subl] = CC_O | CC_S | CC_Z,
|
||||
|
||||
[INDEX_op_movl_T0_eflags] = CC_OSZAPC,
|
||||
[INDEX_op_movl_T0_eflags_vm] = CC_OSZAPC,
|
||||
[INDEX_op_cmc] = CC_C,
|
||||
[INDEX_op_salc] = CC_C,
|
||||
|
||||
@@ -3356,7 +3413,10 @@ static uint16_t opc_write_flags[NB_OPS] = {
|
||||
[INDEX_op_daa] = CC_OSZAPC,
|
||||
|
||||
[INDEX_op_movb_eflags_T0] = CC_S | CC_Z | CC_A | CC_P | CC_C,
|
||||
[INDEX_op_movw_eflags_T0] = CC_OSZAPC,
|
||||
[INDEX_op_movw_eflags_T0_vm] = CC_OSZAPC,
|
||||
[INDEX_op_movl_eflags_T0] = CC_OSZAPC,
|
||||
[INDEX_op_movl_eflags_T0_vm] = CC_OSZAPC,
|
||||
[INDEX_op_clc] = CC_C,
|
||||
[INDEX_op_stc] = CC_C,
|
||||
[INDEX_op_cmc] = CC_C,
|
||||
|
Reference in New Issue
Block a user