mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
This commit was generated by cvs2svn to compensate for changes in r2,
which included commits to RCS files with non-trunk default branches. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
+504
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,37 @@
|
||||
CFLAGS=-Wall -O2 -g
|
||||
LDFLAGS=-g
|
||||
DEFINES=-D_GNU_SOURCE -DGEMU -DDOSEMU #-DNO_TRACE_MSGS
|
||||
|
||||
OBJS= i386/fp87.o i386/interp_main.o i386/interp_modrm.o i386/interp_16_32.o \
|
||||
i386/interp_32_16.o i386/interp_32_32.o i386/emu-utils.o \
|
||||
i386/dis8086.o i386/emu-ldt.o
|
||||
OBJS+= elfload.o main.o thunk.o syscall.o
|
||||
|
||||
SRCS = $(OBJS:.o=.c)
|
||||
|
||||
all: gemu
|
||||
|
||||
gemu: $(OBJS)
|
||||
$(CC) -Wl,-T,i386.ld $(LDFLAGS) -o $@ $(OBJS)
|
||||
|
||||
depend: $(SRCS)
|
||||
$(CC) -MM $(CFLAGS) $^ 1>.depend
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(CFLAGS) $(DEFINES) -c -o $@ $<
|
||||
|
||||
clean:
|
||||
rm -f *.o *~ i386/*.o i386/*~ gemu hello test1 test2 TAGS
|
||||
|
||||
hello: hello.c
|
||||
$(CC) -nostdlib $(CFLAGS) -static $(LDFLAGS) -o $@ $<
|
||||
|
||||
test1: test1.c
|
||||
$(CC) $(CFLAGS) -static $(LDFLAGS) -o $@ $<
|
||||
|
||||
test2: test2.c
|
||||
$(CC) $(CFLAGS) -static $(LDFLAGS) -o $@ $<
|
||||
|
||||
ifneq ($(wildcard .depend),)
|
||||
include .depend
|
||||
endif
|
||||
@@ -0,0 +1,425 @@
|
||||
/*
|
||||
* ELF register definitions..
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
typedef uint32_t elf_greg_t;
|
||||
|
||||
#define ELF_NGREG (sizeof (struct 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
|
||||
|
||||
|
||||
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;
|
||||
|
||||
/* These constants are for the segment types stored in the image headers */
|
||||
#define PT_NULL 0
|
||||
#define PT_LOAD 1
|
||||
#define PT_DYNAMIC 2
|
||||
#define PT_INTERP 3
|
||||
#define PT_NOTE 4
|
||||
#define PT_SHLIB 5
|
||||
#define PT_PHDR 6
|
||||
#define PT_LOPROC 0x70000000
|
||||
#define PT_HIPROC 0x7fffffff
|
||||
|
||||
/* These constants define the different elf file types */
|
||||
#define ET_NONE 0
|
||||
#define ET_REL 1
|
||||
#define ET_EXEC 2
|
||||
#define ET_DYN 3
|
||||
#define ET_CORE 4
|
||||
#define ET_LOPROC 5
|
||||
#define ET_HIPROC 6
|
||||
|
||||
/* These constants define the various ELF target machines */
|
||||
#define EM_NONE 0
|
||||
#define EM_M32 1
|
||||
#define EM_SPARC 2
|
||||
#define EM_386 3
|
||||
#define EM_68K 4
|
||||
#define EM_88K 5
|
||||
#define EM_486 6 /* Perhaps disused */
|
||||
#define EM_860 7
|
||||
|
||||
#define EM_MIPS 8 /* MIPS R3000 (officially, big-endian only) */
|
||||
|
||||
#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 */
|
||||
|
||||
/*
|
||||
* This is an interim value that we will use until the committee comes
|
||||
* up with a final number.
|
||||
*/
|
||||
#define EM_ALPHA 0x9026
|
||||
|
||||
|
||||
/* This is the info that is needed to parse the dynamic section of the file */
|
||||
#define DT_NULL 0
|
||||
#define DT_NEEDED 1
|
||||
#define DT_PLTRELSZ 2
|
||||
#define DT_PLTGOT 3
|
||||
#define DT_HASH 4
|
||||
#define DT_STRTAB 5
|
||||
#define DT_SYMTAB 6
|
||||
#define DT_RELA 7
|
||||
#define DT_RELASZ 8
|
||||
#define DT_RELAENT 9
|
||||
#define DT_STRSZ 10
|
||||
#define DT_SYMENT 11
|
||||
#define DT_INIT 12
|
||||
#define DT_FINI 13
|
||||
#define DT_SONAME 14
|
||||
#define DT_RPATH 15
|
||||
#define DT_SYMBOLIC 16
|
||||
#define DT_REL 17
|
||||
#define DT_RELSZ 18
|
||||
#define DT_RELENT 19
|
||||
#define DT_PLTREL 20
|
||||
#define DT_DEBUG 21
|
||||
#define DT_TEXTREL 22
|
||||
#define DT_JMPREL 23
|
||||
#define DT_LOPROC 0x70000000
|
||||
#define DT_HIPROC 0x7fffffff
|
||||
|
||||
/* This info is needed when parsing the symbol table */
|
||||
#define STB_LOCAL 0
|
||||
#define STB_GLOBAL 1
|
||||
#define STB_WEAK 2
|
||||
|
||||
#define STT_NOTYPE 0
|
||||
#define STT_OBJECT 1
|
||||
#define STT_FUNC 2
|
||||
#define STT_SECTION 3
|
||||
#define STT_FILE 4
|
||||
|
||||
#define ELF32_ST_BIND(x) ((x) >> 4)
|
||||
#define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf)
|
||||
|
||||
/* Symbolic values for the entries in the auxiliary table
|
||||
put on the initial stack */
|
||||
#define AT_NULL 0 /* end of vector */
|
||||
#define AT_IGNORE 1 /* entry should be ignored */
|
||||
#define AT_EXECFD 2 /* file descriptor of program */
|
||||
#define AT_PHDR 3 /* program headers for program */
|
||||
#define AT_PHENT 4 /* size of program header entry */
|
||||
#define AT_PHNUM 5 /* number of program headers */
|
||||
#define AT_PAGESZ 6 /* system page size */
|
||||
#define AT_BASE 7 /* base address of interpreter */
|
||||
#define AT_FLAGS 8 /* flags */
|
||||
#define AT_ENTRY 9 /* entry point of program */
|
||||
#define AT_NOTELF 10 /* program is not ELF */
|
||||
#define AT_UID 11 /* real uid */
|
||||
#define AT_EUID 12 /* effective uid */
|
||||
#define AT_GID 13 /* real gid */
|
||||
#define AT_EGID 14 /* effective gid */
|
||||
|
||||
|
||||
typedef struct dynamic{
|
||||
Elf32_Sword d_tag;
|
||||
union{
|
||||
Elf32_Sword d_val;
|
||||
Elf32_Addr d_ptr;
|
||||
} d_un;
|
||||
} Elf32_Dyn;
|
||||
|
||||
typedef struct {
|
||||
unsigned long long d_tag; /* entry tag value */
|
||||
union {
|
||||
unsigned long long d_val;
|
||||
unsigned long long d_ptr;
|
||||
} d_un;
|
||||
} Elf64_Dyn;
|
||||
|
||||
/* The following are used with relocations */
|
||||
#define ELF32_R_SYM(x) ((x) >> 8)
|
||||
#define ELF32_R_TYPE(x) ((x) & 0xff)
|
||||
|
||||
#define R_386_NONE 0
|
||||
#define R_386_32 1
|
||||
#define R_386_PC32 2
|
||||
#define R_386_GOT32 3
|
||||
#define R_386_PLT32 4
|
||||
#define R_386_COPY 5
|
||||
#define R_386_GLOB_DAT 6
|
||||
#define R_386_JMP_SLOT 7
|
||||
#define R_386_RELATIVE 8
|
||||
#define R_386_GOTOFF 9
|
||||
#define R_386_GOTPC 10
|
||||
#define R_386_NUM 11
|
||||
|
||||
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_Rel;
|
||||
|
||||
typedef struct elf32_rela{
|
||||
Elf32_Addr r_offset;
|
||||
Elf32_Word r_info;
|
||||
Elf32_Sword r_addend;
|
||||
} 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_Rela;
|
||||
|
||||
typedef struct elf32_sym{
|
||||
Elf32_Word st_name;
|
||||
Elf32_Addr st_value;
|
||||
Elf32_Word st_size;
|
||||
unsigned char st_info;
|
||||
unsigned char st_other;
|
||||
Elf32_Half st_shndx;
|
||||
} Elf32_Sym;
|
||||
|
||||
typedef struct elf64_sym {
|
||||
unsigned int 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_Sym;
|
||||
|
||||
|
||||
#define EI_NIDENT 16
|
||||
|
||||
typedef struct elf32_hdr{
|
||||
unsigned char e_ident[EI_NIDENT];
|
||||
Elf32_Half e_type;
|
||||
Elf32_Half e_machine;
|
||||
Elf32_Word e_version;
|
||||
Elf32_Addr e_entry; /* Entry point */
|
||||
Elf32_Off e_phoff;
|
||||
Elf32_Off e_shoff;
|
||||
Elf32_Word e_flags;
|
||||
Elf32_Half e_ehsize;
|
||||
Elf32_Half e_phentsize;
|
||||
Elf32_Half e_phnum;
|
||||
Elf32_Half e_shentsize;
|
||||
Elf32_Half e_shnum;
|
||||
Elf32_Half e_shstrndx;
|
||||
} Elf32_Ehdr;
|
||||
|
||||
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_Ehdr;
|
||||
|
||||
/* These constants define the permissions on sections in the program
|
||||
header, p_flags. */
|
||||
#define PF_R 0x4
|
||||
#define PF_W 0x2
|
||||
#define PF_X 0x1
|
||||
|
||||
typedef struct elf32_phdr{
|
||||
Elf32_Word p_type;
|
||||
Elf32_Off p_offset;
|
||||
Elf32_Addr p_vaddr;
|
||||
Elf32_Addr p_paddr;
|
||||
Elf32_Word p_filesz;
|
||||
Elf32_Word p_memsz;
|
||||
Elf32_Word p_flags;
|
||||
Elf32_Word p_align;
|
||||
} 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_Phdr;
|
||||
|
||||
/* sh_type */
|
||||
#define SHT_NULL 0
|
||||
#define SHT_PROGBITS 1
|
||||
#define SHT_SYMTAB 2
|
||||
#define SHT_STRTAB 3
|
||||
#define SHT_RELA 4
|
||||
#define SHT_HASH 5
|
||||
#define SHT_DYNAMIC 6
|
||||
#define SHT_NOTE 7
|
||||
#define SHT_NOBITS 8
|
||||
#define SHT_REL 9
|
||||
#define SHT_SHLIB 10
|
||||
#define SHT_DYNSYM 11
|
||||
#define SHT_NUM 12
|
||||
#define SHT_LOPROC 0x70000000
|
||||
#define SHT_HIPROC 0x7fffffff
|
||||
#define SHT_LOUSER 0x80000000
|
||||
#define SHT_HIUSER 0xffffffff
|
||||
|
||||
/* sh_flags */
|
||||
#define SHF_WRITE 0x1
|
||||
#define SHF_ALLOC 0x2
|
||||
#define SHF_EXECINSTR 0x4
|
||||
#define SHF_MASKPROC 0xf0000000
|
||||
|
||||
/* special section indexes */
|
||||
#define SHN_UNDEF 0
|
||||
#define SHN_LORESERVE 0xff00
|
||||
#define SHN_LOPROC 0xff00
|
||||
#define SHN_HIPROC 0xff1f
|
||||
#define SHN_ABS 0xfff1
|
||||
#define SHN_COMMON 0xfff2
|
||||
#define SHN_HIRESERVE 0xffff
|
||||
|
||||
typedef struct {
|
||||
Elf32_Word sh_name;
|
||||
Elf32_Word sh_type;
|
||||
Elf32_Word sh_flags;
|
||||
Elf32_Addr sh_addr;
|
||||
Elf32_Off sh_offset;
|
||||
Elf32_Word sh_size;
|
||||
Elf32_Word sh_link;
|
||||
Elf32_Word sh_info;
|
||||
Elf32_Word sh_addralign;
|
||||
Elf32_Word sh_entsize;
|
||||
} 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_Shdr;
|
||||
|
||||
#define EI_MAG0 0 /* e_ident[] indexes */
|
||||
#define EI_MAG1 1
|
||||
#define EI_MAG2 2
|
||||
#define EI_MAG3 3
|
||||
#define EI_CLASS 4
|
||||
#define EI_DATA 5
|
||||
#define EI_VERSION 6
|
||||
#define EI_PAD 7
|
||||
|
||||
#define ELFMAG0 0x7f /* EI_MAG */
|
||||
#define ELFMAG1 'E'
|
||||
#define ELFMAG2 'L'
|
||||
#define ELFMAG3 'F'
|
||||
#define ELFMAG "\177ELF"
|
||||
#define SELFMAG 4
|
||||
|
||||
#define ELFCLASSNONE 0 /* EI_CLASS */
|
||||
#define ELFCLASS32 1
|
||||
#define ELFCLASS64 2
|
||||
#define ELFCLASSNUM 3
|
||||
|
||||
#define ELFDATANONE 0 /* e_ident[EI_DATA] */
|
||||
#define ELFDATA2LSB 1
|
||||
#define ELFDATA2MSB 2
|
||||
|
||||
#define EV_NONE 0 /* e_version, EI_VERSION */
|
||||
#define EV_CURRENT 1
|
||||
#define EV_NUM 2
|
||||
|
||||
/* Notes used in ET_CORE */
|
||||
#define NT_PRSTATUS 1
|
||||
#define NT_PRFPREG 2
|
||||
#define NT_PRPSINFO 3
|
||||
#define NT_TASKSTRUCT 4
|
||||
|
||||
/* Note header in a PT_NOTE section */
|
||||
typedef struct elf32_note {
|
||||
Elf32_Word n_namesz; /* Name size */
|
||||
Elf32_Word n_descsz; /* Content size */
|
||||
Elf32_Word n_type; /* Content type */
|
||||
} 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_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
|
||||
|
||||
#else
|
||||
|
||||
extern Elf64_Dyn _DYNAMIC [];
|
||||
#define elfhdr elf64_hdr
|
||||
#define elf_phdr elf64_phdr
|
||||
#define elf_note elf64_note
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
/* ld script to make i386 Linux kernel
|
||||
* Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
|
||||
*/
|
||||
OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
|
||||
OUTPUT_ARCH(i386)
|
||||
SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/alpha-unknown-linux-gnu/lib);
|
||||
ENTRY(_start)
|
||||
SECTIONS
|
||||
{
|
||||
/* Read-only sections, merged into text segment: */
|
||||
. = 0x60000000 + SIZEOF_HEADERS;
|
||||
.interp : { *(.interp) }
|
||||
.hash : { *(.hash) }
|
||||
.dynsym : { *(.dynsym) }
|
||||
.dynstr : { *(.dynstr) }
|
||||
.gnu.version : { *(.gnu.version) }
|
||||
.gnu.version_d : { *(.gnu.version_d) }
|
||||
.gnu.version_r : { *(.gnu.version_r) }
|
||||
.rel.text :
|
||||
{ *(.rel.text) *(.rel.gnu.linkonce.t*) }
|
||||
.rela.text :
|
||||
{ *(.rela.text) *(.rela.gnu.linkonce.t*) }
|
||||
.rel.data :
|
||||
{ *(.rel.data) *(.rel.gnu.linkonce.d*) }
|
||||
.rela.data :
|
||||
{ *(.rela.data) *(.rela.gnu.linkonce.d*) }
|
||||
.rel.rodata :
|
||||
{ *(.rel.rodata) *(.rel.gnu.linkonce.r*) }
|
||||
.rela.rodata :
|
||||
{ *(.rela.rodata) *(.rela.gnu.linkonce.r*) }
|
||||
.rel.got : { *(.rel.got) }
|
||||
.rela.got : { *(.rela.got) }
|
||||
.rel.ctors : { *(.rel.ctors) }
|
||||
.rela.ctors : { *(.rela.ctors) }
|
||||
.rel.dtors : { *(.rel.dtors) }
|
||||
.rela.dtors : { *(.rela.dtors) }
|
||||
.rel.init : { *(.rel.init) }
|
||||
.rela.init : { *(.rela.init) }
|
||||
.rel.fini : { *(.rel.fini) }
|
||||
.rela.fini : { *(.rela.fini) }
|
||||
.rel.bss : { *(.rel.bss) }
|
||||
.rela.bss : { *(.rela.bss) }
|
||||
.rel.plt : { *(.rel.plt) }
|
||||
.rela.plt : { *(.rela.plt) }
|
||||
.init : { *(.init) } =0x47ff041f
|
||||
.text :
|
||||
{
|
||||
*(.text)
|
||||
/* .gnu.warning sections are handled specially by elf32.em. */
|
||||
*(.gnu.warning)
|
||||
*(.gnu.linkonce.t*)
|
||||
} =0x47ff041f
|
||||
_etext = .;
|
||||
PROVIDE (etext = .);
|
||||
.fini : { *(.fini) } =0x47ff041f
|
||||
.rodata : { *(.rodata) *(.gnu.linkonce.r*) }
|
||||
.rodata1 : { *(.rodata1) }
|
||||
.reginfo : { *(.reginfo) }
|
||||
/* Adjust the address for the data segment. We want to adjust up to
|
||||
the same address within the page on the next page up. */
|
||||
. = ALIGN(0x100000) + (. & (0x100000 - 1));
|
||||
.data :
|
||||
{
|
||||
*(.data)
|
||||
*(.gnu.linkonce.d*)
|
||||
CONSTRUCTORS
|
||||
}
|
||||
.data1 : { *(.data1) }
|
||||
.ctors :
|
||||
{
|
||||
*(.ctors)
|
||||
}
|
||||
.dtors :
|
||||
{
|
||||
*(.dtors)
|
||||
}
|
||||
.plt : { *(.plt) }
|
||||
.got : { *(.got.plt) *(.got) }
|
||||
.dynamic : { *(.dynamic) }
|
||||
/* We want the small data sections together, so single-instruction offsets
|
||||
can access them all, and initialized data all before uninitialized, so
|
||||
we can shorten the on-disk segment size. */
|
||||
.sdata : { *(.sdata) }
|
||||
_edata = .;
|
||||
PROVIDE (edata = .);
|
||||
__bss_start = .;
|
||||
.sbss : { *(.sbss) *(.scommon) }
|
||||
.bss :
|
||||
{
|
||||
*(.dynbss)
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
}
|
||||
_end = . ;
|
||||
PROVIDE (end = .);
|
||||
/* Stabs debugging sections. */
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
.comment 0 : { *(.comment) }
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
/* SGI/MIPS DWARF 2 extensions */
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||
.debug_typenames 0 : { *(.debug_typenames) }
|
||||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
/* These must appear regardless of . */
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,282 @@
|
||||
/* emulated ioctl list */
|
||||
|
||||
IOCTL(TCGETS, IOC_R, MK_PTR(MK_STRUCT(STRUCT_termios)))
|
||||
IOCTL(TCGETS, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios)))
|
||||
IOCTL(TCSETSF, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios)))
|
||||
IOCTL(TCSETSW, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios)))
|
||||
IOCTL(TIOCGWINSZ, IOC_R, MK_PTR(MK_STRUCT(STRUCT_winsize)))
|
||||
IOCTL(TIOCSWINSZ, IOC_W, MK_PTR(MK_STRUCT(STRUCT_winsize)))
|
||||
IOCTL(FIONREAD, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(TCGETA, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(TCSETA, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(TCSETAW, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(TCSETAF, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(TCSBRK, 0, TYPE_INT)
|
||||
IOCTL(TCSBRKP, 0, TYPE_INT)
|
||||
IOCTL(TCXONC, 0, TYPE_INT)
|
||||
IOCTL(TCFLSH, 0, TYPE_INT)
|
||||
IOCTL(TIOCEXCL, 0, TYPE_NULL)
|
||||
IOCTL(TIOCNXCL, 0, TYPE_NULL)
|
||||
IOCTL(TIOCSCTTY, 0, TYPE_INT)
|
||||
IOCTL(TIOCGPGRP, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(TIOCSPGRP, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(TIOCOUTQ, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(TIOCSTI, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(TIOCMGET, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(TIOCMBIS, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(TIOCMBIC, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(TIOCMSET, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(TIOCGSOFTCAR, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(TIOCSSOFTCAR, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(TIOCLINUX, IOC_R | IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(TIOCCONS, 0, TYPE_NULL)
|
||||
IOCTL(TIOCGSERIAL, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(TIOCSSERIAL, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(TIOCPKT, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(FIONBIO, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(TIOCNOTTY, 0, TYPE_NULL)
|
||||
IOCTL(TIOCGETD, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(TIOCSETD, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(FIOCLEX, 0, TYPE_NULL)
|
||||
IOCTL(FIONCLEX, 0, TYPE_NULL)
|
||||
IOCTL(FIOASYNC, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(TIOCGLCKTRMIOS, IOC_R, MK_PTR(MK_STRUCT(STRUCT_termios)))
|
||||
IOCTL(TIOCSLCKTRMIOS, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios)))
|
||||
IOCTL(TIOCSERCONFIG, 0, TYPE_NULL)
|
||||
IOCTL(TIOCSERGETLSR, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(TIOCSERGETMULTI, IOC_R, MK_PTR(MK_STRUCT(STRUCT_serial_multiport_struct)))
|
||||
IOCTL(TIOCSERSETMULTI, IOC_W, MK_PTR(MK_STRUCT(STRUCT_serial_multiport_struct)))
|
||||
IOCTL(TIOCMIWAIT, 0, TYPE_INT)
|
||||
IOCTL(TIOCGICOUNT, IOC_R, MK_PTR(MK_STRUCT(STRUCT_serial_icounter_struct)))
|
||||
|
||||
IOCTL(BLKROSET, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(BLKROGET, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(BLKRRPART, 0, TYPE_NULL)
|
||||
IOCTL(BLKGETSIZE, IOC_R, MK_PTR(TYPE_ULONG))
|
||||
#ifdef BLKGETSIZE64
|
||||
IOCTL(BLKGETSIZE64, IOC_R, MK_PTR(TYPE_ULONGLONG))
|
||||
#endif
|
||||
IOCTL(BLKFLSBUF, 0, TYPE_NULL)
|
||||
IOCTL(BLKRASET, 0, TYPE_INT)
|
||||
IOCTL(BLKRAGET, IOC_R, MK_PTR(TYPE_LONG))
|
||||
#ifdef FIBMAP
|
||||
IOCTL(FIBMAP, IOC_W | IOC_R, MK_PTR(TYPE_LONG))
|
||||
#endif
|
||||
#ifdef FIGETBSZ
|
||||
IOCTL(FIGETBSZ, IOC_R, MK_PTR(TYPE_LONG))
|
||||
#endif
|
||||
|
||||
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))
|
||||
IOCTL(SIOCGIFFLAGS, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_short_ifreq)))
|
||||
IOCTL(SIOCSIFFLAGS, IOC_W, MK_PTR(MK_STRUCT(STRUCT_short_ifreq)))
|
||||
IOCTL(SIOCGIFADDR, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq)))
|
||||
IOCTL(SIOCSIFADDR, IOC_W, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq)))
|
||||
IOCTL(SIOCGIFBRDADDR, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq)))
|
||||
IOCTL(SIOCSIFBRDADDR, IOC_W, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq)))
|
||||
IOCTL(SIOCGIFDSTADDR, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq)))
|
||||
IOCTL(SIOCSIFDSTADDR, IOC_W, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq)))
|
||||
IOCTL(SIOCGIFNETMASK, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq)))
|
||||
IOCTL(SIOCSIFNETMASK, IOC_W, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq)))
|
||||
IOCTL(SIOCGIFHWADDR, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq)))
|
||||
IOCTL(SIOCSIFHWADDR, IOC_W, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq)))
|
||||
IOCTL(SIOCGIFTXQLEN, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq)))
|
||||
IOCTL(SIOCSIFTXQLEN, IOC_W, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq)))
|
||||
IOCTL(SIOCGIFMETRIC, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_int_ifreq)))
|
||||
IOCTL(SIOCSIFMETRIC, IOC_W, MK_PTR(MK_STRUCT(STRUCT_int_ifreq)))
|
||||
IOCTL(SIOCGIFMTU, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_int_ifreq)))
|
||||
IOCTL(SIOCSIFMTU, IOC_W, MK_PTR(MK_STRUCT(STRUCT_int_ifreq)))
|
||||
IOCTL(SIOCGIFMAP, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_ifmap_ifreq)))
|
||||
IOCTL(SIOCSIFMAP, IOC_W, MK_PTR(MK_STRUCT(STRUCT_ifmap_ifreq)))
|
||||
IOCTL(SIOCGIFSLAVE, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_char_ifreq)))
|
||||
IOCTL(SIOCSIFSLAVE, IOC_W, MK_PTR(MK_STRUCT(STRUCT_char_ifreq)))
|
||||
IOCTL(SIOCGIFMEM, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_ptr_ifreq)))
|
||||
IOCTL(SIOCSIFMEM, IOC_W, MK_PTR(MK_STRUCT(STRUCT_ptr_ifreq)))
|
||||
IOCTL(SIOCADDMULTI, IOC_W, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq)))
|
||||
IOCTL(SIOCDELMULTI, IOC_W, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq)))
|
||||
IOCTL(SIOCSIFLINK, 0, TYPE_NULL)
|
||||
IOCTL(SIOCGIFCONF, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_ifconf)))
|
||||
IOCTL(SIOCGIFENCAP, IOC_RW, MK_PTR(TYPE_INT))
|
||||
IOCTL(SIOCSIFENCAP, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(SIOCDARP, IOC_W, MK_PTR(MK_STRUCT(STRUCT_arpreq)))
|
||||
IOCTL(SIOCSARP, IOC_W, MK_PTR(MK_STRUCT(STRUCT_arpreq)))
|
||||
IOCTL(SIOCGARP, IOC_R, MK_PTR(MK_STRUCT(STRUCT_arpreq)))
|
||||
IOCTL(SIOCDRARP, IOC_W, MK_PTR(MK_STRUCT(STRUCT_arpreq)))
|
||||
IOCTL(SIOCSRARP, IOC_W, MK_PTR(MK_STRUCT(STRUCT_arpreq)))
|
||||
IOCTL(SIOCGRARP, IOC_R, MK_PTR(MK_STRUCT(STRUCT_arpreq)))
|
||||
|
||||
IOCTL(CDROMPAUSE, 0, TYPE_NULL)
|
||||
IOCTL(CDROMSTART, 0, TYPE_NULL)
|
||||
IOCTL(CDROMSTOP, 0, TYPE_NULL)
|
||||
IOCTL(CDROMRESUME, 0, TYPE_NULL)
|
||||
IOCTL(CDROMEJECT, 0, TYPE_NULL)
|
||||
IOCTL(CDROMEJECT_SW, 0, TYPE_INT)
|
||||
IOCTL(CDROMCLOSETRAY, 0, TYPE_NULL)
|
||||
IOCTL(CDROMRESET, 0, TYPE_NULL)
|
||||
IOCTL(CDROMPLAYMSF, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(CDROMPLAYTRKIND, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(CDROMREADTOCHDR, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(CDROMREADTOCENTRY, IOC_RW, MK_PTR(TYPE_INT))
|
||||
IOCTL(CDROMVOLCTRL, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(CDROMSUBCHNL, IOC_RW, MK_PTR(TYPE_INT))
|
||||
/* XXX: incorrect (need specific handling) */
|
||||
IOCTL(CDROMREADAUDIO, IOC_W, MK_PTR(MK_STRUCT(STRUCT_cdrom_read_audio)))
|
||||
IOCTL(CDROMREADCOOKED, IOC_RW, MK_PTR(TYPE_INT))
|
||||
IOCTL(CDROMREADRAW, IOC_RW, MK_PTR(TYPE_INT))
|
||||
IOCTL(CDROMREADMODE1, IOC_RW, MK_PTR(TYPE_INT))
|
||||
IOCTL(CDROMREADMODE2, IOC_RW, MK_PTR(TYPE_INT))
|
||||
IOCTL(CDROMREADALL, IOC_RW, MK_PTR(TYPE_INT))
|
||||
IOCTL(CDROMMULTISESSION, IOC_RW, MK_PTR(TYPE_INT))
|
||||
IOCTL(CDROM_GET_UPC, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(CDROMVOLREAD, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(CDROMSEEK, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(CDROMPLAYBLK, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(CDROM_MEDIA_CHANGED, 0, TYPE_NULL)
|
||||
IOCTL(CDROM_SET_OPTIONS, 0, TYPE_INT)
|
||||
IOCTL(CDROM_CLEAR_OPTIONS, 0, TYPE_INT)
|
||||
IOCTL(CDROM_SELECT_SPEED, 0, TYPE_INT)
|
||||
IOCTL(CDROM_SELECT_DISC, 0, TYPE_INT)
|
||||
IOCTL(CDROM_DRIVE_STATUS, 0, TYPE_NULL)
|
||||
IOCTL(CDROM_DISC_STATUS, 0, TYPE_NULL)
|
||||
IOCTL(CDROMAUDIOBUFSIZ, 0, TYPE_INT)
|
||||
|
||||
IOCTL(SNDCTL_COPR_HALT, IOC_RW, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_COPR_LOAD, IOC_RW, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_COPR_RCODE, IOC_RW, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_COPR_RCVMSG, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_COPR_RDATA, IOC_RW, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_COPR_RESET, 0, TYPE_NULL)
|
||||
IOCTL(SNDCTL_COPR_RUN, IOC_RW, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_COPR_SENDMSG, IOC_RW, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_COPR_WCODE, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_COPR_WDATA, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_DSP_CHANNELS, IOC_RW, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_DSP_GETBLKSIZE, IOC_RW, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_DSP_GETCAPS, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_DSP_GETFMTS, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_DSP_GETIPTR, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_DSP_GETISPACE, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_DSP_GETOPTR, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_DSP_GETOSPACE, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_DSP_GETTRIGGER, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_DSP_MAPINBUF, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_DSP_MAPOUTBUF, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_DSP_NONBLOCK, 0, TYPE_NULL)
|
||||
IOCTL(SNDCTL_DSP_POST, 0, TYPE_NULL)
|
||||
IOCTL(SNDCTL_DSP_RESET, 0, TYPE_NULL)
|
||||
IOCTL(SNDCTL_DSP_SETDUPLEX, 0, TYPE_NULL)
|
||||
IOCTL(SNDCTL_DSP_SETFMT, IOC_RW, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_DSP_SETFRAGMENT, IOC_RW, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_DSP_SETSYNCRO, 0, TYPE_NULL)
|
||||
IOCTL(SNDCTL_DSP_SETTRIGGER, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_DSP_SPEED, IOC_RW, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_DSP_STEREO, IOC_RW, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_DSP_SUBDIVIDE, IOC_RW, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_DSP_SYNC, 0, TYPE_NULL)
|
||||
IOCTL(SNDCTL_FM_4OP_ENABLE, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_FM_LOAD_INSTR, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_MIDI_INFO, IOC_RW, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_MIDI_MPUCMD, IOC_RW, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_MIDI_MPUMODE, IOC_RW, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_MIDI_PRETIME, IOC_RW, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_SEQ_CTRLRATE, IOC_RW, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_SEQ_GETINCOUNT, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_SEQ_GETOUTCOUNT, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_SEQ_NRMIDIS, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_SEQ_NRSYNTHS, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_SEQ_OUTOFBAND, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_SEQ_PANIC, 0, TYPE_NULL)
|
||||
IOCTL(SNDCTL_SEQ_PERCMODE, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_SEQ_RESET, 0, TYPE_NULL)
|
||||
IOCTL(SNDCTL_SEQ_RESETSAMPLES, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_SEQ_SYNC, 0, TYPE_NULL)
|
||||
IOCTL(SNDCTL_SEQ_TESTMIDI, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_SEQ_THRESHOLD, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_SYNTH_INFO, IOC_RW, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_SYNTH_MEMAVL, IOC_RW, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_TMR_CONTINUE, 0, TYPE_NULL)
|
||||
IOCTL(SNDCTL_TMR_METRONOME, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_TMR_SELECT, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_TMR_SOURCE, IOC_RW, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_TMR_START, 0, TYPE_NULL)
|
||||
IOCTL(SNDCTL_TMR_STOP, 0, TYPE_NULL)
|
||||
IOCTL(SNDCTL_TMR_TEMPO, IOC_RW, MK_PTR(TYPE_INT))
|
||||
IOCTL(SNDCTL_TMR_TIMEBASE, IOC_RW, MK_PTR(TYPE_INT))
|
||||
|
||||
IOCTL(SOUND_PCM_WRITE_FILTER, IOC_W | IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_PCM_READ_RATE, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_PCM_READ_CHANNELS, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_PCM_READ_BITS, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_PCM_READ_FILTER, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_INFO, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_ACCESS, 0, TYPE_PTRVOID)
|
||||
IOCTL(SOUND_MIXER_PRIVATE1, IOC_RW, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_PRIVATE2, IOC_RW, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_PRIVATE3, IOC_RW, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_PRIVATE4, IOC_RW, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_PRIVATE5, IOC_RW, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_READ_VOLUME, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_READ_BASS, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_READ_TREBLE, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_READ_SYNTH, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_READ_PCM, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_READ_SPEAKER, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_READ_LINE, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_READ_MIC, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_READ_CD, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_READ_IMIX, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_READ_ALTPCM, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_READ_RECLEV, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_READ_IGAIN, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_READ_OGAIN, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_READ_LINE1, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_READ_LINE2, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_READ_LINE3, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_READ_MUTE, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_READ_ENHANCE, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_READ_LOUD, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_READ_RECSRC, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_READ_DEVMASK, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_READ_RECMASK, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_READ_STEREODEVS, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_READ_CAPS, IOC_R, MK_PTR(TYPE_INT))
|
||||
|
||||
IOCTL(SOUND_MIXER_WRITE_VOLUME, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_WRITE_BASS, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_WRITE_TREBLE, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_WRITE_SYNTH, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_WRITE_PCM, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_WRITE_SPEAKER, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_WRITE_LINE, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_WRITE_MIC, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_WRITE_CD, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_WRITE_IMIX, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_WRITE_ALTPCM, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_WRITE_RECLEV, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_WRITE_IGAIN, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_WRITE_OGAIN, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_WRITE_LINE1, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_WRITE_LINE2, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_WRITE_LINE3, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_WRITE_MUTE, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_WRITE_ENHANCE, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_WRITE_LOUD, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(SOUND_MIXER_WRITE_RECSRC, IOC_W, MK_PTR(TYPE_INT))
|
||||
|
||||
IOCTL(HDIO_GETGEO, IOC_R, MK_PTR(MK_STRUCT(STRUCT_hd_geometry)))
|
||||
IOCTL(HDIO_GET_UNMASKINTR, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(HDIO_GET_MULTCOUNT, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(HDIO_GET_IDENTITY, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(HDIO_GET_KEEPSETTINGS, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(HDIO_GET_NOWERR, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(HDIO_GET_DMA, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(HDIO_GET_32BIT, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(HDIO_DRIVE_CMD, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(HDIO_SET_UNMASKINTR, 0, TYPE_INT)
|
||||
IOCTL(HDIO_SET_MULTCOUNT, 0, TYPE_INT)
|
||||
IOCTL(HDIO_SET_KEEPSETTINGS, 0, TYPE_INT)
|
||||
IOCTL(HDIO_SET_NOWERR, 0, TYPE_INT)
|
||||
IOCTL(HDIO_SET_DMA, 0, TYPE_INT)
|
||||
IOCTL(HDIO_SET_32BIT, 0, TYPE_INT)
|
||||
IOCTL(HDIO_SET_PIO_MODE, 0, TYPE_INT)
|
||||
@@ -0,0 +1,310 @@
|
||||
/*
|
||||
* emu main
|
||||
*
|
||||
* Copyright (c) 2003 Fabrice Bellard
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <elf.h>
|
||||
#include <endian.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "gemu.h"
|
||||
|
||||
#include "i386/hsw_interp.h"
|
||||
|
||||
unsigned long x86_stack_size;
|
||||
unsigned long stktop;
|
||||
|
||||
void gemu_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
/* virtual x86 CPU stuff */
|
||||
|
||||
extern int invoke_code16(Interp_ENV *, int, int);
|
||||
extern int invoke_code32(Interp_ENV *, int);
|
||||
extern char *e_print_cpuemu_regs(ENVPARAMS, int is32);
|
||||
extern char *e_emu_disasm(ENVPARAMS, unsigned char *org, int is32);
|
||||
extern void init_npu(void);
|
||||
|
||||
Interp_ENV env_global;
|
||||
Interp_ENV *envp_global;
|
||||
|
||||
QWORD EMUtime = 0;
|
||||
|
||||
int CEmuStat = 0;
|
||||
|
||||
long instr_count;
|
||||
|
||||
/* who will initialize this? */
|
||||
unsigned long io_bitmap[IO_BITMAP_SIZE+1];
|
||||
|
||||
/* debug flag, 0=disable 1..9=level */
|
||||
int d_emu = 0;
|
||||
|
||||
unsigned long CRs[5] =
|
||||
{
|
||||
0x00000013, /* valid bits: 0xe005003f */
|
||||
0x00000000, /* invalid */
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000
|
||||
};
|
||||
|
||||
/*
|
||||
* DR0-3 = linear address of breakpoint 0-3
|
||||
* DR4=5 = reserved
|
||||
* DR6 b0-b3 = BP active
|
||||
* b13 = BD
|
||||
* b14 = BS
|
||||
* b15 = BT
|
||||
* DR7 b0-b1 = G:L bp#0
|
||||
* b2-b3 = G:L bp#1
|
||||
* b4-b5 = G:L bp#2
|
||||
* b6-b7 = G:L bp#3
|
||||
* b8-b9 = GE:LE
|
||||
* b13 = GD
|
||||
* b16-19= LLRW bp#0 LL=00(1),01(2),11(4)
|
||||
* b20-23= LLRW bp#1 RW=00(x),01(w),11(rw)
|
||||
* b24-27= LLRW bp#2
|
||||
* b28-31= LLRW bp#3
|
||||
*/
|
||||
unsigned long DRs[8] =
|
||||
{
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0xffff1ff0,
|
||||
0x00000400,
|
||||
0xffff1ff0,
|
||||
0x00000400
|
||||
};
|
||||
|
||||
unsigned long TRs[2] =
|
||||
{
|
||||
0x00000000,
|
||||
0x00000000
|
||||
};
|
||||
|
||||
void FatalAppExit(UINT wAction, LPCSTR lpText)
|
||||
{
|
||||
fprintf(stderr, "Fatal error '%s' in CPU\n", lpText);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int e_debug_check(unsigned char *PC)
|
||||
{
|
||||
register unsigned long d7 = DRs[7];
|
||||
|
||||
if (d7&0x03) {
|
||||
if (d7&0x30000) return 0; /* only execute(00) bkp */
|
||||
if ((long)PC==DRs[0]) {
|
||||
e_printf("DBRK: DR0 hit at %p\n",PC);
|
||||
DRs[6] |= 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (d7&0x0c) {
|
||||
if (d7&0x300000) return 0;
|
||||
if ((long)PC==DRs[1]) {
|
||||
e_printf("DBRK: DR1 hit at %p\n",PC);
|
||||
DRs[6] |= 2;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (d7&0x30) {
|
||||
if (d7&0x3000000) return 0;
|
||||
if ((long)PC==DRs[2]) {
|
||||
e_printf("DBRK: DR2 hit at %p\n",PC);
|
||||
DRs[6] |= 4;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (d7&0xc0) {
|
||||
if (d7&0x30000000) return 0;
|
||||
if ((long)PC==DRs[3]) {
|
||||
e_printf("DBRK: DR3 hit at %p\n",PC);
|
||||
DRs[6] |= 8;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Debug stuff */
|
||||
void logstr(unsigned long mask, const char *fmt,...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
/* unconditional message into debug log and stderr */
|
||||
#undef error
|
||||
void error(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int PortIO(DWORD port, DWORD value, UINT size, BOOL is_write)
|
||||
{
|
||||
fprintf(stderr, "IO: %s port=0x%lx value=0x%lx size=%d",
|
||||
is_write ? "write" : "read", port, value, size);
|
||||
return value;
|
||||
}
|
||||
|
||||
void LogProcName(WORD wSel, WORD wOff, WORD wAction)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void INT_handler(int num, void *env)
|
||||
{
|
||||
fprintf(stderr, "EM86: int %d\n", num);
|
||||
}
|
||||
|
||||
/***********************************************************/
|
||||
|
||||
/* XXX: currently we use LDT entries */
|
||||
#define __USER_CS (0x23|4)
|
||||
#define __USER_DS (0x2B|4)
|
||||
|
||||
void usage(void)
|
||||
{
|
||||
printf("gemu version 0.1, Copyright (c) 2003 Fabrice Bellard\n"
|
||||
"usage: gemu program [arguments...]\n"
|
||||
"Linux x86 emulator\n"
|
||||
);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *filename;
|
||||
struct pt_regs regs1, *regs = ®s1;
|
||||
struct image_info info1, *info = &info1;
|
||||
Interp_ENV *env;
|
||||
|
||||
if (argc <= 1)
|
||||
usage();
|
||||
|
||||
filename = argv[1];
|
||||
|
||||
/* Zero out regs */
|
||||
memset(regs, 0, sizeof(struct pt_regs));
|
||||
|
||||
/* Zero out image_info */
|
||||
memset(info, 0, sizeof(struct image_info));
|
||||
|
||||
if(elf_exec(filename, argv+1, __environ, regs, info) != 0) {
|
||||
printf("Error loading %s\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#if 0
|
||||
printf("start_brk 0x%08lx\n" , info->start_brk);
|
||||
printf("end_code 0x%08lx\n" , info->end_code);
|
||||
printf("start_code 0x%08lx\n" , info->start_code);
|
||||
printf("end_data 0x%08lx\n" , info->end_data);
|
||||
printf("start_stack 0x%08lx\n" , info->start_stack);
|
||||
printf("brk 0x%08lx\n" , info->brk);
|
||||
printf("esp 0x%08lx\n" , regs->esp);
|
||||
printf("eip 0x%08lx\n" , regs->eip);
|
||||
#endif
|
||||
|
||||
target_set_brk((char *)info->brk);
|
||||
syscall_init();
|
||||
|
||||
env = &env_global;
|
||||
envp_global = env;
|
||||
memset(env, 0, sizeof(Interp_ENV));
|
||||
|
||||
env->rax.e = regs->eax;
|
||||
env->rbx.e = regs->ebx;
|
||||
env->rcx.e = regs->ecx;
|
||||
env->rdx.e = regs->edx;
|
||||
env->rsi.esi = regs->esi;
|
||||
env->rdi.edi = regs->edi;
|
||||
env->rbp.ebp = regs->ebp;
|
||||
env->rsp.esp = regs->esp;
|
||||
env->cs.cs = __USER_CS;
|
||||
env->ds.ds = __USER_DS;
|
||||
env->es.es = __USER_DS;
|
||||
env->ss.ss = __USER_DS;
|
||||
env->fs.fs = __USER_DS;
|
||||
env->gs.gs = __USER_DS;
|
||||
env->trans_addr = regs->eip;
|
||||
|
||||
LDT[__USER_CS >> 3].w86Flags = DF_PRESENT | DF_PAGES | DF_32;
|
||||
LDT[__USER_CS >> 3].dwSelLimit = 0xfffff;
|
||||
LDT[__USER_CS >> 3].lpSelBase = NULL;
|
||||
|
||||
LDT[__USER_DS >> 3].w86Flags = DF_PRESENT | DF_PAGES | DF_32;
|
||||
LDT[__USER_DS >> 3].dwSelLimit = 0xfffff;
|
||||
LDT[__USER_DS >> 3].lpSelBase = NULL;
|
||||
init_npu();
|
||||
|
||||
for(;;) {
|
||||
int err;
|
||||
uint8_t *pc;
|
||||
|
||||
err = invoke_code32(env, -1);
|
||||
env->trans_addr = env->return_addr;
|
||||
pc = env->seg_regs[0] + env->trans_addr;
|
||||
switch(err) {
|
||||
case EXCP0D_GPF:
|
||||
if (pc[0] == 0xcd && pc[1] == 0x80) {
|
||||
/* syscall */
|
||||
env->trans_addr += 2;
|
||||
env->rax.e = do_syscall(env->rax.e,
|
||||
env->rbx.e,
|
||||
env->rcx.e,
|
||||
env->rdx.e,
|
||||
env->rsi.esi,
|
||||
env->rdi.edi,
|
||||
env->rbp.ebp);
|
||||
} else {
|
||||
goto trap_error;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
trap_error:
|
||||
fprintf(stderr, "GEMU: Unknown error %d, aborting\n", err);
|
||||
d_emu = 9;
|
||||
fprintf(stderr, "%s\n%s\n",
|
||||
e_print_cpuemu_regs(env, 1),
|
||||
e_emu_disasm(env,pc,1));
|
||||
abort();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
#ifndef GEMU_H
|
||||
#define GEMU_H
|
||||
|
||||
#include "thunk.h"
|
||||
|
||||
struct pt_regs {
|
||||
long ebx;
|
||||
long ecx;
|
||||
long edx;
|
||||
long esi;
|
||||
long edi;
|
||||
long ebp;
|
||||
long eax;
|
||||
int xds;
|
||||
int xes;
|
||||
long orig_eax;
|
||||
long eip;
|
||||
int xcs;
|
||||
long eflags;
|
||||
long esp;
|
||||
int xss;
|
||||
};
|
||||
|
||||
/* This struct is used to hold certain information about the image.
|
||||
* Basically, it replicates in user space what would be certain
|
||||
* task_struct fields in the kernel
|
||||
*/
|
||||
struct image_info {
|
||||
unsigned long start_code;
|
||||
unsigned long end_code;
|
||||
unsigned long end_data;
|
||||
unsigned long start_brk;
|
||||
unsigned long brk;
|
||||
unsigned long start_mmap;
|
||||
unsigned long mmap;
|
||||
unsigned long rss;
|
||||
unsigned long start_stack;
|
||||
unsigned long arg_start;
|
||||
unsigned long arg_end;
|
||||
unsigned long env_start;
|
||||
unsigned long env_end;
|
||||
unsigned long entry;
|
||||
int personality;
|
||||
};
|
||||
|
||||
int elf_exec(const char * filename, char ** argv, char ** envp,
|
||||
struct pt_regs * regs, struct image_info *infop);
|
||||
|
||||
void target_set_brk(char *new_brk);
|
||||
void syscall_init(void);
|
||||
long do_syscall(int num, long arg1, long arg2, long arg3,
|
||||
long arg4, long arg5, long arg6);
|
||||
void gemu_log(const char *fmt, ...) __attribute__((format(printf,1,2)));
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Emulation of Linux signal handling
|
||||
*
|
||||
* Copyright (c) 2003 Fabrice Bellard
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <signal.h>
|
||||
#include <sys/ucontext.h>
|
||||
|
||||
/* Algorithm strongly inspired from em86 : we queue the signals so
|
||||
that we can handle them at precise points in the emulated code. */
|
||||
|
||||
struct emulated_sigaction {
|
||||
struct target_sigaction sa;
|
||||
int nb_pending;
|
||||
struct target_siginfo info;
|
||||
};
|
||||
|
||||
struct emulated_sigaction sigact_table[NSIG];
|
||||
int signal_pending;
|
||||
|
||||
static inline int host_to_target_signal(int sig)
|
||||
{
|
||||
return sig;
|
||||
}
|
||||
|
||||
static inline int target_to_host_signal(int sig)
|
||||
{
|
||||
return sig;
|
||||
}
|
||||
|
||||
void signal_init(void)
|
||||
{
|
||||
struct sigaction act;
|
||||
int i;
|
||||
|
||||
/* set all host signal handlers */
|
||||
sigemptyset(&act.sa_mask);
|
||||
act.sa_flags = SA_SIGINFO;
|
||||
act.sa_sigaction = host_signal_handler;
|
||||
for(i = 1; i < NSIG; i++) {
|
||||
sigaction(i, &sa, NULL);
|
||||
}
|
||||
|
||||
memset(sigact_table, 0, sizeof(sigact_table));
|
||||
}
|
||||
|
||||
static void host_signal_handler(int host_signum, siginfo_t *info,
|
||||
void *puc)
|
||||
{
|
||||
struct ucontext *uc = puc;
|
||||
int signum;
|
||||
/* get target signal number */
|
||||
signum = host_to_target(host_signum);
|
||||
if (signum >= TARGET_NSIG)
|
||||
return;
|
||||
/* we save the old mask */
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void process_pending_signals(void)
|
||||
{
|
||||
int signum;
|
||||
target_ulong _sa_handler;
|
||||
|
||||
struct emulated_sigaction *esig;
|
||||
|
||||
if (!signal_pending)
|
||||
return;
|
||||
|
||||
esig = sigact_table;
|
||||
for(signum = 1; signum < TARGET_NSIG; signum++) {
|
||||
if (esig->nb_pending != 0)
|
||||
goto handle_signal;
|
||||
esig++;
|
||||
}
|
||||
/* if no signal is pending, just return */
|
||||
signal_pending = 0;
|
||||
return;
|
||||
handle_signal:
|
||||
_sa_handler = esig->sa._sa_handler;
|
||||
if (_sa_handler == TARGET_SIG_DFL) {
|
||||
/* default handling
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,283 @@
|
||||
|
||||
/* common syscall defines for all architectures */
|
||||
|
||||
#define SOCKOP_socket 1
|
||||
#define SOCKOP_bind 2
|
||||
#define SOCKOP_connect 3
|
||||
#define SOCKOP_listen 4
|
||||
#define SOCKOP_accept 5
|
||||
#define SOCKOP_getsockname 6
|
||||
#define SOCKOP_getpeername 7
|
||||
#define SOCKOP_socketpair 8
|
||||
#define SOCKOP_send 9
|
||||
#define SOCKOP_recv 10
|
||||
#define SOCKOP_sendto 11
|
||||
#define SOCKOP_recvfrom 12
|
||||
#define SOCKOP_shutdown 13
|
||||
#define SOCKOP_setsockopt 14
|
||||
#define SOCKOP_getsockopt 15
|
||||
#define SOCKOP_sendmsg 16
|
||||
#define SOCKOP_recvmsg 17
|
||||
|
||||
struct target_timeval {
|
||||
target_long tv_sec;
|
||||
target_long tv_usec;
|
||||
};
|
||||
|
||||
struct target_iovec {
|
||||
target_long iov_base; /* Starting address */
|
||||
target_long iov_len; /* Number of bytes */
|
||||
};
|
||||
|
||||
struct target_rusage {
|
||||
struct target_timeval ru_utime; /* user time used */
|
||||
struct target_timeval ru_stime; /* system time used */
|
||||
target_long ru_maxrss; /* maximum resident set size */
|
||||
target_long ru_ixrss; /* integral shared memory size */
|
||||
target_long ru_idrss; /* integral unshared data size */
|
||||
target_long ru_isrss; /* integral unshared stack size */
|
||||
target_long ru_minflt; /* page reclaims */
|
||||
target_long ru_majflt; /* page faults */
|
||||
target_long ru_nswap; /* swaps */
|
||||
target_long ru_inblock; /* block input operations */
|
||||
target_long ru_oublock; /* block output operations */
|
||||
target_long ru_msgsnd; /* messages sent */
|
||||
target_long ru_msgrcv; /* messages received */
|
||||
target_long ru_nsignals; /* signals received */
|
||||
target_long ru_nvcsw; /* voluntary context switches */
|
||||
target_long ru_nivcsw; /* involuntary " */
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int val[2];
|
||||
} kernel_fsid_t;
|
||||
|
||||
struct statfs {
|
||||
int f_type;
|
||||
int f_bsize;
|
||||
int f_blocks;
|
||||
int f_bfree;
|
||||
int f_bavail;
|
||||
int f_files;
|
||||
int f_ffree;
|
||||
kernel_fsid_t f_fsid;
|
||||
int f_namelen;
|
||||
int f_spare[6];
|
||||
};
|
||||
|
||||
/* mostly generic signal stuff */
|
||||
#define TARGET_SIG_DFL ((target_long)0) /* default signal handling */
|
||||
#define TARGET_SIG_IGN ((target_long)1) /* ignore signal */
|
||||
#define TARGET_SIG_ERR ((target_long)-1) /* error return from signal */
|
||||
|
||||
#ifdef TARGET_MIPS
|
||||
#define TARGET_NSIG 128
|
||||
#else
|
||||
#define TARGET_NSIG 64
|
||||
#endif
|
||||
#define TARGET_NSIG_BPW TARGET_LONG_BITS
|
||||
#define TARGET_NSIG_WORDS (TARGET_NSIG / TARGET_NSIG_BPW)
|
||||
|
||||
typedef struct {
|
||||
target_ulong sig[TARGET_NSIG_WORDS];
|
||||
} target_sigset_t;
|
||||
|
||||
/* Networking ioctls */
|
||||
#define TARGET_SIOCADDRT 0x890B /* add routing table entry */
|
||||
#define TARGET_SIOCDELRT 0x890C /* delete routing table entry */
|
||||
#define TARGET_SIOCGIFNAME 0x8910 /* get iface name */
|
||||
#define TARGET_SIOCSIFLINK 0x8911 /* set iface channel */
|
||||
#define TARGET_SIOCGIFCONF 0x8912 /* get iface list */
|
||||
#define TARGET_SIOCGIFFLAGS 0x8913 /* get flags */
|
||||
#define TARGET_SIOCSIFFLAGS 0x8914 /* set flags */
|
||||
#define TARGET_SIOCGIFADDR 0x8915 /* get PA address */
|
||||
#define TARGET_SIOCSIFADDR 0x8916 /* set PA address */
|
||||
#define TARGET_SIOCGIFDSTADDR 0x8917 /* get remote PA address */
|
||||
#define TARGET_SIOCSIFDSTADDR 0x8918 /* set remote PA address */
|
||||
#define TARGET_SIOCGIFBRDADDR 0x8919 /* get broadcast PA address */
|
||||
#define TARGET_SIOCSIFBRDADDR 0x891a /* set broadcast PA address */
|
||||
#define TARGET_SIOCGIFNETMASK 0x891b /* get network PA mask */
|
||||
#define TARGET_SIOCSIFNETMASK 0x891c /* set network PA mask */
|
||||
#define TARGET_SIOCGIFMETRIC 0x891d /* get metric */
|
||||
#define TARGET_SIOCSIFMETRIC 0x891e /* set metric */
|
||||
#define TARGET_SIOCGIFMEM 0x891f /* get memory address (BSD) */
|
||||
#define TARGET_SIOCSIFMEM 0x8920 /* set memory address (BSD) */
|
||||
#define TARGET_SIOCGIFMTU 0x8921 /* get MTU size */
|
||||
#define TARGET_SIOCSIFMTU 0x8922 /* set MTU size */
|
||||
#define TARGET_SIOCSIFHWADDR 0x8924 /* set hardware address (NI) */
|
||||
#define TARGET_SIOCGIFENCAP 0x8925 /* get/set slip encapsulation */
|
||||
#define TARGET_SIOCSIFENCAP 0x8926
|
||||
#define TARGET_SIOCGIFHWADDR 0x8927 /* Get hardware address */
|
||||
#define TARGET_SIOCGIFSLAVE 0x8929 /* Driver slaving support */
|
||||
#define TARGET_SIOCSIFSLAVE 0x8930
|
||||
#define TARGET_SIOCADDMULTI 0x8931 /* Multicast address lists */
|
||||
#define TARGET_SIOCDELMULTI 0x8932
|
||||
|
||||
/* Bridging control calls */
|
||||
#define TARGET_SIOCGIFBR 0x8940 /* Bridging support */
|
||||
#define TARGET_SIOCSIFBR 0x8941 /* Set bridging options */
|
||||
|
||||
#define TARGET_SIOCGIFTXQLEN 0x8942 /* Get the tx queue length */
|
||||
#define TARGET_SIOCSIFTXQLEN 0x8943 /* Set the tx queue length */
|
||||
|
||||
/* ARP cache control calls. */
|
||||
#define TARGET_OLD_SIOCDARP 0x8950 /* old delete ARP table entry */
|
||||
#define TARGET_OLD_SIOCGARP 0x8951 /* old get ARP table entry */
|
||||
#define TARGET_OLD_SIOCSARP 0x8952 /* old set ARP table entry */
|
||||
#define TARGET_SIOCDARP 0x8953 /* delete ARP table entry */
|
||||
#define TARGET_SIOCGARP 0x8954 /* get ARP table entry */
|
||||
#define TARGET_SIOCSARP 0x8955 /* set ARP table entry */
|
||||
|
||||
/* RARP cache control calls. */
|
||||
#define TARGET_SIOCDRARP 0x8960 /* delete RARP table entry */
|
||||
#define TARGET_SIOCGRARP 0x8961 /* get RARP table entry */
|
||||
#define TARGET_SIOCSRARP 0x8962 /* set RARP table entry */
|
||||
|
||||
/* Driver configuration calls */
|
||||
#define TARGET_SIOCGIFMAP 0x8970 /* Get device parameters */
|
||||
#define TARGET_SIOCSIFMAP 0x8971 /* Set device parameters */
|
||||
|
||||
/* DLCI configuration calls */
|
||||
#define TARGET_SIOCADDDLCI 0x8980 /* Create new DLCI device */
|
||||
#define TARGET_SIOCDELDLCI 0x8981 /* Delete DLCI device */
|
||||
|
||||
|
||||
/* From <linux/fs.h> */
|
||||
|
||||
#define TARGET_BLKROSET TARGET_IO(0x12,93) /* set device read-only (0 = read-write) */
|
||||
#define TARGET_BLKROGET TARGET_IO(0x12,94) /* get read-only status (0 = read_write) */
|
||||
#define TARGET_BLKRRPART TARGET_IO(0x12,95) /* re-read partition table */
|
||||
#define TARGET_BLKGETSIZE TARGET_IO(0x12,96) /* return device size /512 (long *arg) */
|
||||
#define TARGET_BLKFLSBUF TARGET_IO(0x12,97) /* flush buffer cache */
|
||||
#define TARGET_BLKRASET TARGET_IO(0x12,98) /* Set read ahead for block device */
|
||||
#define TARGET_BLKRAGET TARGET_IO(0x12,99) /* get current read ahead setting */
|
||||
#define TARGET_BLKFRASET TARGET_IO(0x12,100)/* set filesystem (mm/filemap.c) read-ahead */
|
||||
#define TARGET_BLKFRAGET TARGET_IO(0x12,101)/* get filesystem (mm/filemap.c) read-ahead */
|
||||
#define TARGET_BLKSECTSET TARGET_IO(0x12,102)/* set max sectors per request (ll_rw_blk.c) */
|
||||
#define TARGET_BLKSECTGET TARGET_IO(0x12,103)/* get max sectors per request (ll_rw_blk.c) */
|
||||
#define TARGET_BLKSSZGET TARGET_IO(0x12,104)/* get block device sector size */
|
||||
/* A jump here: 108-111 have been used for various private purposes. */
|
||||
#define TARGET_BLKBSZGET TARGET_IOR(0x12,112,sizeof(int))
|
||||
#define TARGET_BLKBSZSET TARGET_IOW(0x12,113,sizeof(int))
|
||||
#define TARGET_BLKGETSIZE64 TARGET_IOR(0x12,114,sizeof(uint64_t)) /* return device size in bytes (u64 *arg) */
|
||||
#define TARGET_FIBMAP TARGET_IO(0x00,1) /* bmap access */
|
||||
#define TARGET_FIGETBSZ TARGET_IO(0x00,2) /* get the block size used for bmap */
|
||||
|
||||
/* cdrom commands */
|
||||
#define TARGET_CDROMPAUSE 0x5301 /* Pause Audio Operation */
|
||||
#define TARGET_CDROMRESUME 0x5302 /* Resume paused Audio Operation */
|
||||
#define TARGET_CDROMPLAYMSF 0x5303 /* Play Audio MSF (struct cdrom_msf) */
|
||||
#define TARGET_CDROMPLAYTRKIND 0x5304 /* Play Audio Track/index
|
||||
(struct cdrom_ti) */
|
||||
#define TARGET_CDROMREADTOCHDR 0x5305 /* Read TOC header
|
||||
(struct cdrom_tochdr) */
|
||||
#define TARGET_CDROMREADTOCENTRY 0x5306 /* Read TOC entry
|
||||
(struct cdrom_tocentry) */
|
||||
#define TARGET_CDROMSTOP 0x5307 /* Stop the cdrom drive */
|
||||
#define TARGET_CDROMSTART 0x5308 /* Start the cdrom drive */
|
||||
#define TARGET_CDROMEJECT 0x5309 /* Ejects the cdrom media */
|
||||
#define TARGET_CDROMVOLCTRL 0x530a /* Control output volume
|
||||
(struct cdrom_volctrl) */
|
||||
#define TARGET_CDROMSUBCHNL 0x530b /* Read subchannel data
|
||||
(struct cdrom_subchnl) */
|
||||
#define TARGET_CDROMREADMODE2 0x530c /* Read TARGET_CDROM mode 2 data (2336 Bytes)
|
||||
(struct cdrom_read) */
|
||||
#define TARGET_CDROMREADMODE1 0x530d /* Read TARGET_CDROM mode 1 data (2048 Bytes)
|
||||
(struct cdrom_read) */
|
||||
#define TARGET_CDROMREADAUDIO 0x530e /* (struct cdrom_read_audio) */
|
||||
#define TARGET_CDROMEJECT_SW 0x530f /* enable(1)/disable(0) auto-ejecting */
|
||||
#define TARGET_CDROMMULTISESSION 0x5310 /* Obtain the start-of-last-session
|
||||
address of multi session disks
|
||||
(struct cdrom_multisession) */
|
||||
#define TARGET_CDROM_GET_MCN 0x5311 /* Obtain the "Universal Product Code"
|
||||
if available (struct cdrom_mcn) */
|
||||
#define TARGET_CDROM_GET_UPC TARGET_CDROM_GET_MCN /* This one is depricated,
|
||||
but here anyway for compatability */
|
||||
#define TARGET_CDROMRESET 0x5312 /* hard-reset the drive */
|
||||
#define TARGET_CDROMVOLREAD 0x5313 /* Get the drive's volume setting
|
||||
(struct cdrom_volctrl) */
|
||||
#define TARGET_CDROMREADRAW 0x5314 /* read data in raw mode (2352 Bytes)
|
||||
(struct cdrom_read) */
|
||||
/*
|
||||
* These ioctls are used only used in aztcd.c and optcd.c
|
||||
*/
|
||||
#define TARGET_CDROMREADCOOKED 0x5315 /* read data in cooked mode */
|
||||
#define TARGET_CDROMSEEK 0x5316 /* seek msf address */
|
||||
|
||||
/*
|
||||
* This ioctl is only used by the scsi-cd driver.
|
||||
It is for playing audio in logical block addressing mode.
|
||||
*/
|
||||
#define TARGET_CDROMPLAYBLK 0x5317 /* (struct cdrom_blk) */
|
||||
|
||||
/*
|
||||
* These ioctls are only used in optcd.c
|
||||
*/
|
||||
#define TARGET_CDROMREADALL 0x5318 /* read all 2646 bytes */
|
||||
|
||||
/*
|
||||
* These ioctls are (now) only in ide-cd.c for controlling
|
||||
* drive spindown time. They should be implemented in the
|
||||
* Uniform driver, via generic packet commands, GPCMD_MODE_SELECT_10,
|
||||
* GPCMD_MODE_SENSE_10 and the GPMODE_POWER_PAGE...
|
||||
* -Erik
|
||||
*/
|
||||
#define TARGET_CDROMGETSPINDOWN 0x531d
|
||||
#define TARGET_CDROMSETSPINDOWN 0x531e
|
||||
|
||||
/*
|
||||
* These ioctls are implemented through the uniform CD-ROM driver
|
||||
* They _will_ be adopted by all CD-ROM drivers, when all the CD-ROM
|
||||
* drivers are eventually ported to the uniform CD-ROM driver interface.
|
||||
*/
|
||||
#define TARGET_CDROMCLOSETRAY 0x5319 /* pendant of CDROMEJECT */
|
||||
#define TARGET_CDROM_SET_OPTIONS 0x5320 /* Set behavior options */
|
||||
#define TARGET_CDROM_CLEAR_OPTIONS 0x5321 /* Clear behavior options */
|
||||
#define TARGET_CDROM_SELECT_SPEED 0x5322 /* Set the CD-ROM speed */
|
||||
#define TARGET_CDROM_SELECT_DISC 0x5323 /* Select disc (for juke-boxes) */
|
||||
#define TARGET_CDROM_MEDIA_CHANGED 0x5325 /* Check is media changed */
|
||||
#define TARGET_CDROM_DRIVE_STATUS 0x5326 /* Get tray position, etc. */
|
||||
#define TARGET_CDROM_DISC_STATUS 0x5327 /* Get disc type, etc. */
|
||||
#define TARGET_CDROM_CHANGER_NSLOTS 0x5328 /* Get number of slots */
|
||||
#define TARGET_CDROM_LOCKDOOR 0x5329 /* lock or unlock door */
|
||||
#define TARGET_CDROM_DEBUG 0x5330 /* Turn debug messages on/off */
|
||||
#define TARGET_CDROM_GET_CAPABILITY 0x5331 /* get capabilities */
|
||||
|
||||
/* Note that scsi/scsi_ioctl.h also uses 0x5382 - 0x5386.
|
||||
* Future CDROM ioctls should be kept below 0x537F
|
||||
*/
|
||||
|
||||
/* This ioctl is only used by sbpcd at the moment */
|
||||
#define TARGET_CDROMAUDIOBUFSIZ 0x5382 /* set the audio buffer size */
|
||||
/* conflict with SCSI_IOCTL_GET_IDLUN */
|
||||
|
||||
/* DVD-ROM Specific ioctls */
|
||||
#define TARGET_DVD_READ_STRUCT 0x5390 /* Read structure */
|
||||
#define TARGET_DVD_WRITE_STRUCT 0x5391 /* Write structure */
|
||||
#define TARGET_DVD_AUTH 0x5392 /* Authentication */
|
||||
|
||||
#define TARGET_CDROM_SEND_PACKET 0x5393 /* send a packet to the drive */
|
||||
#define TARGET_CDROM_NEXT_WRITABLE 0x5394 /* get next writable block */
|
||||
#define TARGET_CDROM_LAST_WRITTEN 0x5395 /* get last block written on disc */
|
||||
|
||||
/* HD commands */
|
||||
|
||||
/* hd/ide ctl's that pass (arg) ptrs to user space are numbered 0x030n/0x031n */
|
||||
#define TARGET_HDIO_GETGEO 0x0301 /* get device geometry */
|
||||
#define TARGET_HDIO_GET_UNMASKINTR 0x0302 /* get current unmask setting */
|
||||
#define TARGET_HDIO_GET_MULTCOUNT 0x0304 /* get current IDE blockmode setting */
|
||||
#define TARGET_HDIO_GET_IDENTITY 0x0307 /* get IDE identification info */
|
||||
#define TARGET_HDIO_GET_KEEPSETTINGS 0x0308 /* get keep-settings-on-reset flag */
|
||||
#define TARGET_HDIO_GET_32BIT 0x0309 /* get current io_32bit setting */
|
||||
#define TARGET_HDIO_GET_NOWERR 0x030a /* get ignore-write-error flag */
|
||||
#define TARGET_HDIO_GET_DMA 0x030b /* get use-dma flag */
|
||||
#define TARGET_HDIO_DRIVE_CMD 0x031f /* execute a special drive command */
|
||||
|
||||
/* hd/ide ctl's that pass (arg) non-ptr values are numbered 0x032n/0x033n */
|
||||
#define TARGET_HDIO_SET_MULTCOUNT 0x0321 /* change IDE blockmode */
|
||||
#define TARGET_HDIO_SET_UNMASKINTR 0x0322 /* permit other irqs during I/O */
|
||||
#define TARGET_HDIO_SET_KEEPSETTINGS 0x0323 /* keep ioctl settings on reset */
|
||||
#define TARGET_HDIO_SET_32BIT 0x0324 /* change io_32bit flags */
|
||||
#define TARGET_HDIO_SET_NOWERR 0x0325 /* change ignore-write-error flag */
|
||||
#define TARGET_HDIO_SET_DMA 0x0326 /* change use-dma flag */
|
||||
#define TARGET_HDIO_SET_PIO_MODE 0x0327 /* reconfig interface to new speed */
|
||||
@@ -0,0 +1,64 @@
|
||||
STRUCT_SPECIAL(termios)
|
||||
|
||||
STRUCT(winsize,
|
||||
TYPE_SHORT, TYPE_SHORT, TYPE_SHORT, TYPE_SHORT)
|
||||
|
||||
STRUCT(serial_multiport_struct,
|
||||
TYPE_INT, TYPE_INT, TYPE_CHAR, TYPE_CHAR, TYPE_INT, TYPE_CHAR, TYPE_CHAR,
|
||||
TYPE_INT, TYPE_CHAR, TYPE_CHAR, TYPE_INT, TYPE_CHAR, TYPE_CHAR, TYPE_INT,
|
||||
MK_ARRAY(TYPE_INT, 32))
|
||||
|
||||
STRUCT(serial_icounter_struct,
|
||||
TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, MK_ARRAY(TYPE_INT, 16))
|
||||
|
||||
STRUCT(sockaddr,
|
||||
TYPE_SHORT, MK_ARRAY(TYPE_CHAR, 14))
|
||||
|
||||
STRUCT(rtentry,
|
||||
TYPE_ULONG, MK_STRUCT(STRUCT_sockaddr), MK_STRUCT(STRUCT_sockaddr), MK_STRUCT(STRUCT_sockaddr),
|
||||
TYPE_SHORT, TYPE_SHORT, TYPE_ULONG, TYPE_PTRVOID, TYPE_SHORT, TYPE_PTRVOID,
|
||||
TYPE_ULONG, TYPE_ULONG, TYPE_SHORT)
|
||||
|
||||
STRUCT(ifmap,
|
||||
TYPE_ULONG, TYPE_ULONG, TYPE_SHORT, TYPE_CHAR, TYPE_CHAR, TYPE_CHAR,
|
||||
/* Spare 3 bytes */
|
||||
TYPE_CHAR, TYPE_CHAR, TYPE_CHAR)
|
||||
|
||||
/* The *_ifreq_list arrays deal with the fact that struct ifreq has unions */
|
||||
|
||||
STRUCT(sockaddr_ifreq,
|
||||
MK_ARRAY(TYPE_CHAR, IFNAMSIZ), MK_STRUCT(STRUCT_sockaddr))
|
||||
|
||||
STRUCT(short_ifreq,
|
||||
MK_ARRAY(TYPE_CHAR, IFNAMSIZ), TYPE_SHORT)
|
||||
|
||||
STRUCT(int_ifreq,
|
||||
MK_ARRAY(TYPE_CHAR, IFNAMSIZ), TYPE_INT)
|
||||
|
||||
STRUCT(ifmap_ifreq,
|
||||
MK_ARRAY(TYPE_CHAR, IFNAMSIZ), MK_STRUCT(STRUCT_ifmap))
|
||||
|
||||
STRUCT(char_ifreq,
|
||||
MK_ARRAY(TYPE_CHAR, IFNAMSIZ),
|
||||
MK_ARRAY(TYPE_CHAR, IFNAMSIZ))
|
||||
|
||||
STRUCT(ptr_ifreq,
|
||||
MK_ARRAY(TYPE_CHAR, IFNAMSIZ), TYPE_PTRVOID)
|
||||
|
||||
STRUCT(ifconf,
|
||||
TYPE_INT, TYPE_PTRVOID)
|
||||
|
||||
STRUCT(arpreq,
|
||||
MK_STRUCT(STRUCT_sockaddr), MK_STRUCT(STRUCT_sockaddr), TYPE_INT, MK_STRUCT(STRUCT_sockaddr),
|
||||
MK_ARRAY(TYPE_CHAR, 16))
|
||||
|
||||
STRUCT(arpreq_old,
|
||||
MK_STRUCT(STRUCT_sockaddr), MK_STRUCT(STRUCT_sockaddr), TYPE_INT, MK_STRUCT(STRUCT_sockaddr))
|
||||
|
||||
STRUCT(cdrom_read_audio,
|
||||
TYPE_CHAR, TYPE_CHAR, TYPE_CHAR, TYPE_CHAR, TYPE_CHAR, TYPE_INT, TYPE_PTRVOID,
|
||||
TYPE_NULL)
|
||||
|
||||
STRUCT(hd_geometry,
|
||||
TYPE_CHAR, TYPE_CHAR, TYPE_SHORT, TYPE_ULONG)
|
||||
|
||||
+760
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,315 @@
|
||||
/*
|
||||
* Generic thunking code to convert data between host and target CPU
|
||||
*
|
||||
* Copyright (c) 2003 Fabrice Bellard
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "gemu.h"
|
||||
#include "thunk.h"
|
||||
|
||||
//#define DEBUG
|
||||
|
||||
#define MAX_STRUCTS 128
|
||||
|
||||
/* XXX: make it dynamic */
|
||||
static StructEntry struct_entries[MAX_STRUCTS];
|
||||
|
||||
static inline int thunk_type_size(const argtype *type_ptr, int is_host)
|
||||
{
|
||||
int type, size;
|
||||
const StructEntry *se;
|
||||
|
||||
type = *type_ptr;
|
||||
switch(type) {
|
||||
case TYPE_CHAR:
|
||||
return 1;
|
||||
case TYPE_SHORT:
|
||||
return 2;
|
||||
case TYPE_INT:
|
||||
return 4;
|
||||
case TYPE_LONGLONG:
|
||||
case TYPE_ULONGLONG:
|
||||
return 8;
|
||||
case TYPE_LONG:
|
||||
case TYPE_ULONG:
|
||||
case TYPE_PTRVOID:
|
||||
case TYPE_PTR:
|
||||
if (is_host) {
|
||||
return HOST_LONG_SIZE;
|
||||
} else {
|
||||
return TARGET_LONG_SIZE;
|
||||
}
|
||||
break;
|
||||
case TYPE_ARRAY:
|
||||
size = type_ptr[1];
|
||||
return size * thunk_type_size(type_ptr + 2, is_host);
|
||||
case TYPE_STRUCT:
|
||||
se = struct_entries + type_ptr[1];
|
||||
return se->size[is_host];
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int thunk_type_align(const argtype *type_ptr, int is_host)
|
||||
{
|
||||
int type;
|
||||
const StructEntry *se;
|
||||
|
||||
type = *type_ptr;
|
||||
switch(type) {
|
||||
case TYPE_CHAR:
|
||||
return 1;
|
||||
case TYPE_SHORT:
|
||||
return 2;
|
||||
case TYPE_INT:
|
||||
return 4;
|
||||
case TYPE_LONGLONG:
|
||||
case TYPE_ULONGLONG:
|
||||
return 8;
|
||||
case TYPE_LONG:
|
||||
case TYPE_ULONG:
|
||||
case TYPE_PTRVOID:
|
||||
case TYPE_PTR:
|
||||
if (is_host) {
|
||||
return HOST_LONG_SIZE;
|
||||
} else {
|
||||
return TARGET_LONG_SIZE;
|
||||
}
|
||||
break;
|
||||
case TYPE_ARRAY:
|
||||
return thunk_type_align(type_ptr + 2, is_host);
|
||||
case TYPE_STRUCT:
|
||||
se = struct_entries + type_ptr[1];
|
||||
return se->align[is_host];
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static inline const argtype *thunk_type_next(const argtype *type_ptr)
|
||||
{
|
||||
int type;
|
||||
|
||||
type = *type_ptr++;
|
||||
switch(type) {
|
||||
case TYPE_CHAR:
|
||||
case TYPE_SHORT:
|
||||
case TYPE_INT:
|
||||
case TYPE_LONGLONG:
|
||||
case TYPE_ULONGLONG:
|
||||
case TYPE_LONG:
|
||||
case TYPE_ULONG:
|
||||
case TYPE_PTRVOID:
|
||||
return type_ptr;
|
||||
case TYPE_PTR:
|
||||
return thunk_type_next(type_ptr);
|
||||
case TYPE_ARRAY:
|
||||
return thunk_type_next(type_ptr + 1);
|
||||
case TYPE_STRUCT:
|
||||
return type_ptr + 1;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void thunk_register_struct(int id, const char *name, const argtype *types)
|
||||
{
|
||||
const argtype *type_ptr;
|
||||
StructEntry *se;
|
||||
int nb_fields, offset, max_align, align, size, i, j;
|
||||
|
||||
se = struct_entries + id;
|
||||
|
||||
/* first we count the number of fields */
|
||||
type_ptr = types;
|
||||
nb_fields = 0;
|
||||
while (*type_ptr != TYPE_NULL) {
|
||||
type_ptr = thunk_type_next(type_ptr);
|
||||
nb_fields++;
|
||||
}
|
||||
se->field_types = types;
|
||||
se->nb_fields = nb_fields;
|
||||
se->name = name;
|
||||
#ifdef DEBUG
|
||||
printf("struct %s: id=%d nb_fields=%d\n",
|
||||
se->name, id, se->nb_fields);
|
||||
#endif
|
||||
/* now we can alloc the data */
|
||||
|
||||
for(i = 0;i < 2; i++) {
|
||||
offset = 0;
|
||||
max_align = 1;
|
||||
se->field_offsets[i] = malloc(nb_fields * sizeof(int));
|
||||
type_ptr = se->field_types;
|
||||
for(j = 0;j < nb_fields; j++) {
|
||||
size = thunk_type_size(type_ptr, i);
|
||||
align = thunk_type_align(type_ptr, i);
|
||||
offset = (offset + align - 1) & ~(align - 1);
|
||||
se->field_offsets[i][j] = offset;
|
||||
offset += size;
|
||||
if (align > max_align)
|
||||
max_align = align;
|
||||
}
|
||||
offset = (offset + max_align - 1) & ~(max_align - 1);
|
||||
se->size[i] = offset;
|
||||
se->align[i] = max_align;
|
||||
#ifdef DEBUG
|
||||
printf("%s: size=%d align=%d\n",
|
||||
i == THUNK_HOST ? "host" : "target", offset, max_align);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void thunk_register_struct_direct(int id, const char *name, StructEntry *se1)
|
||||
{
|
||||
StructEntry *se;
|
||||
se = struct_entries + id;
|
||||
*se = *se1;
|
||||
se->name = name;
|
||||
}
|
||||
|
||||
|
||||
/* now we can define the main conversion functions */
|
||||
const argtype *thunk_convert(void *dst, const void *src,
|
||||
const argtype *type_ptr, int to_host)
|
||||
{
|
||||
int type;
|
||||
|
||||
type = *type_ptr++;
|
||||
switch(type) {
|
||||
case TYPE_CHAR:
|
||||
*(uint8_t *)dst = *(uint8_t *)src;
|
||||
break;
|
||||
case TYPE_SHORT:
|
||||
*(uint16_t *)dst = tswap16(*(uint16_t *)src);
|
||||
break;
|
||||
case TYPE_INT:
|
||||
*(uint32_t *)dst = tswap32(*(uint32_t *)src);
|
||||
break;
|
||||
case TYPE_LONGLONG:
|
||||
case TYPE_ULONGLONG:
|
||||
*(uint64_t *)dst = tswap64(*(uint64_t *)src);
|
||||
break;
|
||||
#if HOST_LONG_BITS == 32 && TARGET_LONG_BITS == 32
|
||||
case TYPE_LONG:
|
||||
case TYPE_ULONG:
|
||||
case TYPE_PTRVOID:
|
||||
*(uint32_t *)dst = tswap32(*(uint32_t *)src);
|
||||
break;
|
||||
#elif HOST_LONG_BITS == 64 && TARGET_LONG_BITS == 32
|
||||
case TYPE_LONG:
|
||||
case TYPE_ULONG:
|
||||
case TYPE_PTRVOID:
|
||||
if (target_to_host) {
|
||||
*(uint64_t *)dst = tswap32(*(uint32_t *)src);
|
||||
} else {
|
||||
*(uint32_t *)dst = tswap32(*(uint64_t *)src & 0xffffffff);
|
||||
}
|
||||
break;
|
||||
#else
|
||||
#error unsupported conversion
|
||||
#endif
|
||||
case TYPE_ARRAY:
|
||||
{
|
||||
int array_length, i, dst_size, src_size;
|
||||
const uint8_t *s;
|
||||
uint8_t *d;
|
||||
|
||||
array_length = *type_ptr++;
|
||||
dst_size = thunk_type_size(type_ptr, to_host);
|
||||
src_size = thunk_type_size(type_ptr, 1 - to_host);
|
||||
d = dst;
|
||||
s = src;
|
||||
for(i = 0;i < array_length; i++) {
|
||||
thunk_convert(d, s, type_ptr, to_host);
|
||||
d += dst_size;
|
||||
s += src_size;
|
||||
}
|
||||
type_ptr = thunk_type_next(type_ptr);
|
||||
}
|
||||
break;
|
||||
case TYPE_STRUCT:
|
||||
{
|
||||
int i;
|
||||
const StructEntry *se;
|
||||
const uint8_t *s;
|
||||
uint8_t *d;
|
||||
const argtype *field_types;
|
||||
const int *dst_offsets, *src_offsets;
|
||||
|
||||
se = struct_entries + *type_ptr++;
|
||||
if (se->convert[0] != NULL) {
|
||||
/* specific conversion is needed */
|
||||
(*se->convert[to_host])(dst, src);
|
||||
} else {
|
||||
/* standard struct conversion */
|
||||
field_types = se->field_types;
|
||||
dst_offsets = se->field_offsets[to_host];
|
||||
src_offsets = se->field_offsets[1 - to_host];
|
||||
d = dst;
|
||||
s = src;
|
||||
for(i = 0;i < se->nb_fields; i++) {
|
||||
field_types = thunk_convert(d + dst_offsets[i],
|
||||
s + src_offsets[i],
|
||||
field_types, to_host);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Invalid type 0x%x\n", type);
|
||||
break;
|
||||
}
|
||||
return type_ptr;
|
||||
}
|
||||
|
||||
/* from em86 */
|
||||
|
||||
/* Utility function: Table-driven functions to translate bitmasks
|
||||
* between X86 and Alpha formats...
|
||||
*/
|
||||
unsigned int target_to_host_bitmask(unsigned int x86_mask,
|
||||
bitmask_transtbl * trans_tbl)
|
||||
{
|
||||
bitmask_transtbl * btp;
|
||||
unsigned int alpha_mask = 0;
|
||||
|
||||
for(btp = trans_tbl; btp->x86_mask && btp->alpha_mask; btp++) {
|
||||
if((x86_mask & btp->x86_mask) == btp->x86_bits) {
|
||||
alpha_mask |= btp->alpha_bits;
|
||||
}
|
||||
}
|
||||
return(alpha_mask);
|
||||
}
|
||||
|
||||
unsigned int host_to_target_bitmask(unsigned int alpha_mask,
|
||||
bitmask_transtbl * trans_tbl)
|
||||
{
|
||||
bitmask_transtbl * btp;
|
||||
unsigned int x86_mask = 0;
|
||||
|
||||
for(btp = trans_tbl; btp->x86_mask && btp->alpha_mask; btp++) {
|
||||
if((alpha_mask & btp->alpha_mask) == btp->alpha_bits) {
|
||||
x86_mask |= btp->x86_mask;
|
||||
}
|
||||
}
|
||||
return(x86_mask);
|
||||
}
|
||||
@@ -0,0 +1,195 @@
|
||||
#ifndef THUNK_H
|
||||
#define THUNK_H
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <byteswap.h>
|
||||
|
||||
#undef WORDS_BIGENDIAN
|
||||
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||
#define WORDS_BIGENDIAN
|
||||
#endif
|
||||
|
||||
#ifdef WORD_BIGENDIAN
|
||||
#define BSWAP_NEEDED
|
||||
#endif
|
||||
|
||||
/* XXX: auto autoconf */
|
||||
#define TARGET_I386
|
||||
#define TARGET_LONG_BITS 32
|
||||
|
||||
|
||||
#if defined(__alpha__)
|
||||
#define HOST_LONG_BITS 64
|
||||
#else
|
||||
#define HOST_LONG_BITS 32
|
||||
#endif
|
||||
|
||||
#define TARGET_LONG_SIZE (TARGET_LONG_BITS / 8)
|
||||
#define HOST_LONG_SIZE (TARGET_LONG_BITS / 8)
|
||||
|
||||
static inline uint16_t bswap16(uint16_t x)
|
||||
{
|
||||
return bswap_16(x);
|
||||
}
|
||||
|
||||
static inline uint32_t bswap32(uint32_t x)
|
||||
{
|
||||
return bswap_32(x);
|
||||
}
|
||||
|
||||
static inline uint64_t bswap64(uint64_t x)
|
||||
{
|
||||
return bswap_64(x);
|
||||
}
|
||||
|
||||
static void inline bswap16s(uint16_t *s)
|
||||
{
|
||||
*s = bswap16(*s);
|
||||
}
|
||||
|
||||
static void inline bswap32s(uint32_t *s)
|
||||
{
|
||||
*s = bswap32(*s);
|
||||
}
|
||||
|
||||
static void inline bswap64s(uint64_t *s)
|
||||
{
|
||||
*s = bswap64(*s);
|
||||
}
|
||||
|
||||
#ifdef BSWAP_NEEDED
|
||||
|
||||
static inline uint16_t tswap16(uint16_t s)
|
||||
{
|
||||
return bswap16(s);
|
||||
}
|
||||
|
||||
static inline uint32_t tswap32(uint32_t s)
|
||||
{
|
||||
return bswap32(s);
|
||||
}
|
||||
|
||||
static inline uint64_t tswap64(uint64_t s)
|
||||
{
|
||||
return bswap64(s);
|
||||
}
|
||||
|
||||
static void inline tswap16s(uint16_t *s)
|
||||
{
|
||||
*s = bswap16(*s);
|
||||
}
|
||||
|
||||
static void inline tswap32s(uint32_t *s)
|
||||
{
|
||||
*s = bswap32(*s);
|
||||
}
|
||||
|
||||
static void inline tswap64s(uint64_t *s)
|
||||
{
|
||||
*s = bswap64(*s);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static inline uint16_t tswap16(uint16_t s)
|
||||
{
|
||||
return s;
|
||||
}
|
||||
|
||||
static inline uint32_t tswap32(uint32_t s)
|
||||
{
|
||||
return s;
|
||||
}
|
||||
|
||||
static inline uint64_t tswap64(uint64_t s)
|
||||
{
|
||||
return s;
|
||||
}
|
||||
|
||||
static void inline tswap16s(uint16_t *s)
|
||||
{
|
||||
}
|
||||
|
||||
static void inline tswap32s(uint32_t *s)
|
||||
{
|
||||
}
|
||||
|
||||
static void inline tswap64s(uint64_t *s)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if TARGET_LONG_SIZE == 4
|
||||
#define tswapl(s) tswap32(s)
|
||||
#define tswapls(s) tswap32s((uint32_t *)(s))
|
||||
#else
|
||||
#define tswapl(s) tswap64(s)
|
||||
#define tswapls(s) tswap64s((uint64_t *)(s))
|
||||
#endif
|
||||
|
||||
#if TARGET_LONG_SIZE == 4
|
||||
typedef int32_t target_long;
|
||||
typedef uint32_t target_ulong;
|
||||
#elif TARGET_LONG_SIZE == 8
|
||||
typedef int64_t target_long;
|
||||
typedef uint64_t target_ulong;
|
||||
#else
|
||||
#error TARGET_LONG_SIZE undefined
|
||||
#endif
|
||||
|
||||
/* types enums definitions */
|
||||
|
||||
typedef enum argtype {
|
||||
TYPE_NULL,
|
||||
TYPE_CHAR,
|
||||
TYPE_SHORT,
|
||||
TYPE_INT,
|
||||
TYPE_LONG,
|
||||
TYPE_ULONG,
|
||||
TYPE_PTRVOID, /* pointer on unknown data */
|
||||
TYPE_LONGLONG,
|
||||
TYPE_ULONGLONG,
|
||||
TYPE_PTR,
|
||||
TYPE_ARRAY,
|
||||
TYPE_STRUCT,
|
||||
} argtype;
|
||||
|
||||
#define MK_PTR(type) TYPE_PTR, type
|
||||
#define MK_ARRAY(type, size) TYPE_ARRAY, size, type
|
||||
#define MK_STRUCT(id) TYPE_STRUCT, id
|
||||
|
||||
#define THUNK_TARGET 0
|
||||
#define THUNK_HOST 1
|
||||
|
||||
typedef struct {
|
||||
/* standard struct handling */
|
||||
const argtype *field_types;
|
||||
int nb_fields;
|
||||
int *field_offsets[2];
|
||||
/* special handling */
|
||||
void (*convert[2])(void *dst, const void *src);
|
||||
int size[2];
|
||||
int align[2];
|
||||
const char *name;
|
||||
} StructEntry;
|
||||
|
||||
/* Translation table for bitmasks... */
|
||||
typedef struct bitmask_transtbl {
|
||||
unsigned int x86_mask;
|
||||
unsigned int x86_bits;
|
||||
unsigned int alpha_mask;
|
||||
unsigned int alpha_bits;
|
||||
} bitmask_transtbl;
|
||||
|
||||
void thunk_register_struct(int id, const char *name, const argtype *types);
|
||||
void thunk_register_struct_direct(int id, const char *name, StructEntry *se1);
|
||||
const argtype *thunk_convert(void *dst, const void *src,
|
||||
const argtype *type_ptr, int to_host);
|
||||
|
||||
unsigned int target_to_host_bitmask(unsigned int x86_mask,
|
||||
bitmask_transtbl * trans_tbl);
|
||||
unsigned int host_to_target_bitmask(unsigned int alpha_mask,
|
||||
bitmask_transtbl * trans_tbl);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user