Commit bc51c5c989c12b3936b78c5772a3308629a7484c

Authored by bellard
1 parent 50691463

initial x86-64 host support (Gwenole Beauchesne)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@670 c046a42c-6fe2-441c-8c8c-71466251a162

Too many changes to show.

To preserve performance only 12 of 17 files are displayed.

Changelog
... ... @@ -18,6 +18,7 @@ version 0.5.3:
18 18 - generic removable device support
19 19 - support of CD-ROM change
20 20 - multiple network interface support
  21 + - initial x86-64 host support (Gwenole Beauchesne)
21 22  
22 23 version 0.5.2:
23 24  
... ...
Makefile.target
... ... @@ -80,6 +80,11 @@ LDFLAGS+=-Wl,-shared
80 80 endif
81 81 endif
82 82  
  83 +ifeq ($(ARCH),amd64)
  84 +OP_CFLAGS=$(CFLAGS) -falign-functions=0
  85 +LDFLAGS+=-Wl,-T,$(SRC_PATH)/amd64.ld
  86 +endif
  87 +
83 88 ifeq ($(ARCH),ppc)
84 89 OP_CFLAGS=$(CFLAGS)
85 90 LDFLAGS+=-Wl,-T,$(SRC_PATH)/ppc.ld
... ... @@ -174,6 +179,12 @@ endif
174 179 # NOTE: the disassembler code is only needed for debugging
175 180 LIBOBJS+=disas.o
176 181 ifeq ($(findstring i386, $(TARGET_ARCH) $(ARCH)),i386)
  182 +USE_I386_DIS=y
  183 +endif
  184 +ifeq ($(findstring amd64, $(TARGET_ARCH) $(ARCH)),amd64)
  185 +USE_I386_DIS=y
  186 +endif
  187 +ifdef USE_I386_DIS
177 188 LIBOBJS+=i386-dis.o
178 189 endif
179 190 ifeq ($(findstring alpha, $(TARGET_ARCH) $(ARCH)),alpha)
... ...
amd64.ld 0 → 100644
  1 +/* Default linker script, for normal executables */
  2 +OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
  3 +OUTPUT_ARCH(i386:x86-64)
  4 +ENTRY(_start)
  5 +SEARCH_DIR("/lib64"); SEARCH_DIR("/usr/lib64"); SEARCH_DIR("/usr/local/lib64");
  6 +SECTIONS
  7 +{
  8 + /* Read-only sections, merged into text segment: */
  9 + . = 0x60000000 + SIZEOF_HEADERS;
  10 + .interp : { *(.interp) }
  11 + .hash : { *(.hash) }
  12 + .dynsym : { *(.dynsym) }
  13 + .dynstr : { *(.dynstr) }
  14 + .gnu.version : { *(.gnu.version) }
  15 + .gnu.version_d : { *(.gnu.version_d) }
  16 + .gnu.version_r : { *(.gnu.version_r) }
  17 + .rel.init : { *(.rel.init) }
  18 + .rela.init : { *(.rela.init) }
  19 + .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) }
  20 + .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }
  21 + .rel.fini : { *(.rel.fini) }
  22 + .rela.fini : { *(.rela.fini) }
  23 + .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) }
  24 + .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }
  25 + .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
  26 + .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }
  27 + .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) }
  28 + .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }
  29 + .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) }
  30 + .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }
  31 + .rel.ctors : { *(.rel.ctors) }
  32 + .rela.ctors : { *(.rela.ctors) }
  33 + .rel.dtors : { *(.rel.dtors) }
  34 + .rela.dtors : { *(.rela.dtors) }
  35 + .rel.got : { *(.rel.got) }
  36 + .rela.got : { *(.rela.got) }
  37 + .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) }
  38 + .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
  39 + .rel.plt : { *(.rel.plt) }
  40 + .rela.plt : { *(.rela.plt) }
  41 + .init :
  42 + {
  43 + KEEP (*(.init))
  44 + } =0x90909090
  45 + .plt : { *(.plt) }
  46 + .text :
  47 + {
  48 + *(.text .stub .text.* .gnu.linkonce.t.*)
  49 + /* .gnu.warning sections are handled specially by elf32.em. */
  50 + *(.gnu.warning)
  51 + } =0x90909090
  52 + .fini :
  53 + {
  54 + KEEP (*(.fini))
  55 + } =0x90909090
  56 + PROVIDE (__etext = .);
  57 + PROVIDE (_etext = .);
  58 + PROVIDE (etext = .);
  59 + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
  60 + .rodata1 : { *(.rodata1) }
  61 + .eh_frame_hdr : { *(.eh_frame_hdr) }
  62 + .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
  63 + .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table) }
  64 + /* Adjust the address for the data segment. We want to adjust up to
  65 + the same address within the page on the next page up. */
  66 + . = ALIGN (0x100000) - ((0x100000 - .) & (0x100000 - 1)); . = DATA_SEGMENT_ALIGN (0x100000, 0x1000);
  67 + /* Ensure the __preinit_array_start label is properly aligned. We
  68 + could instead move the label definition inside the section, but
  69 + the linker would then create the section even if it turns out to
  70 + be empty, which isn't pretty. */
  71 + . = ALIGN(64 / 8);
  72 + PROVIDE (__preinit_array_start = .);
  73 + .preinit_array : { *(.preinit_array) }
  74 + PROVIDE (__preinit_array_end = .);
  75 + PROVIDE (__init_array_start = .);
  76 + .init_array : { *(.init_array) }
  77 + PROVIDE (__init_array_end = .);
  78 + PROVIDE (__fini_array_start = .);
  79 + .fini_array : { *(.fini_array) }
  80 + PROVIDE (__fini_array_end = .);
  81 + .data :
  82 + {
  83 + *(.data .data.* .gnu.linkonce.d.*)
  84 + SORT(CONSTRUCTORS)
  85 + }
  86 + .data1 : { *(.data1) }
  87 + .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
  88 + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
  89 + .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }
  90 + .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table) }
  91 + .dynamic : { *(.dynamic) }
  92 + .ctors :
  93 + {
  94 + /* gcc uses crtbegin.o to find the start of
  95 + the constructors, so we make sure it is
  96 + first. Because this is a wildcard, it
  97 + doesn't matter if the user does not
  98 + actually link against crtbegin.o; the
  99 + linker won't look for a file to match a
  100 + wildcard. The wildcard also means that it
  101 + doesn't matter which directory crtbegin.o
  102 + is in. */
  103 + KEEP (*crtbegin.o(.ctors))
  104 + /* We don't want to include the .ctor section from
  105 + from the crtend.o file until after the sorted ctors.
  106 + The .ctor section from the crtend file contains the
  107 + end of ctors marker and it must be last */
  108 + KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors))
  109 + KEEP (*(SORT(.ctors.*)))
  110 + KEEP (*(.ctors))
  111 + }
  112 + .dtors :
  113 + {
  114 + KEEP (*crtbegin.o(.dtors))
  115 + KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))
  116 + KEEP (*(SORT(.dtors.*)))
  117 + KEEP (*(.dtors))
  118 + }
  119 + .jcr : { KEEP (*(.jcr)) }
  120 + .got : { *(.got.plt) *(.got) }
  121 + _edata = .;
  122 + PROVIDE (edata = .);
  123 + __bss_start = .;
  124 + .bss :
  125 + {
  126 + *(.dynbss)
  127 + *(.bss .bss.* .gnu.linkonce.b.*)
  128 + *(COMMON)
  129 + /* Align here to ensure that the .bss section occupies space up to
  130 + _end. Align after .bss to ensure correct alignment even if the
  131 + .bss section disappears because there are no input sections. */
  132 + . = ALIGN(64 / 8);
  133 + }
  134 + . = ALIGN(64 / 8);
  135 + _end = .;
  136 + PROVIDE (end = .);
  137 + . = DATA_SEGMENT_END (.);
  138 + /* Stabs debugging sections. */
  139 + .stab 0 : { *(.stab) }
  140 + .stabstr 0 : { *(.stabstr) }
  141 + .stab.excl 0 : { *(.stab.excl) }
  142 + .stab.exclstr 0 : { *(.stab.exclstr) }
  143 + .stab.index 0 : { *(.stab.index) }
  144 + .stab.indexstr 0 : { *(.stab.indexstr) }
  145 + .comment 0 : { *(.comment) }
  146 + /* DWARF debug sections.
  147 + Symbols in the DWARF debugging sections are relative to the beginning
  148 + of the section so we begin them at 0. */
  149 + /* DWARF 1 */
  150 + .debug 0 : { *(.debug) }
  151 + .line 0 : { *(.line) }
  152 + /* GNU DWARF 1 extensions */
  153 + .debug_srcinfo 0 : { *(.debug_srcinfo) }
  154 + .debug_sfnames 0 : { *(.debug_sfnames) }
  155 + /* DWARF 1.1 and DWARF 2 */
  156 + .debug_aranges 0 : { *(.debug_aranges) }
  157 + .debug_pubnames 0 : { *(.debug_pubnames) }
  158 + /* DWARF 2 */
  159 + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
  160 + .debug_abbrev 0 : { *(.debug_abbrev) }
  161 + .debug_line 0 : { *(.debug_line) }
  162 + .debug_frame 0 : { *(.debug_frame) }
  163 + .debug_str 0 : { *(.debug_str) }
  164 + .debug_loc 0 : { *(.debug_loc) }
  165 + .debug_macinfo 0 : { *(.debug_macinfo) }
  166 + /* SGI/MIPS DWARF 2 extensions */
  167 + .debug_weaknames 0 : { *(.debug_weaknames) }
  168 + .debug_funcnames 0 : { *(.debug_funcnames) }
  169 + .debug_typenames 0 : { *(.debug_typenames) }
  170 + .debug_varnames 0 : { *(.debug_varnames) }
  171 +}
  172 +/* Default linker script, for normal executables */
  173 +OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
  174 +OUTPUT_ARCH(i386:x86-64)
  175 +ENTRY(_start)
  176 +SEARCH_DIR("/lib64"); SEARCH_DIR("/usr/lib64"); SEARCH_DIR("/usr/local/lib64");
  177 +SECTIONS
  178 +{
  179 + /* Read-only sections, merged into text segment: */
  180 + . = 0x60000000 + SIZEOF_HEADERS;
  181 + .interp : { *(.interp) }
  182 + .hash : { *(.hash) }
  183 + .dynsym : { *(.dynsym) }
  184 + .dynstr : { *(.dynstr) }
  185 + .gnu.version : { *(.gnu.version) }
  186 + .gnu.version_d : { *(.gnu.version_d) }
  187 + .gnu.version_r : { *(.gnu.version_r) }
  188 + .rel.init : { *(.rel.init) }
  189 + .rela.init : { *(.rela.init) }
  190 + .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) }
  191 + .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }
  192 + .rel.fini : { *(.rel.fini) }
  193 + .rela.fini : { *(.rela.fini) }
  194 + .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) }
  195 + .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }
  196 + .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
  197 + .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }
  198 + .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) }
  199 + .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }
  200 + .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) }
  201 + .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }
  202 + .rel.ctors : { *(.rel.ctors) }
  203 + .rela.ctors : { *(.rela.ctors) }
  204 + .rel.dtors : { *(.rel.dtors) }
  205 + .rela.dtors : { *(.rela.dtors) }
  206 + .rel.got : { *(.rel.got) }
  207 + .rela.got : { *(.rela.got) }
  208 + .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) }
  209 + .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
  210 + .rel.plt : { *(.rel.plt) }
  211 + .rela.plt : { *(.rela.plt) }
  212 + .init :
  213 + {
  214 + KEEP (*(.init))
  215 + } =0x90909090
  216 + .plt : { *(.plt) }
  217 + .text :
  218 + {
  219 + *(.text .stub .text.* .gnu.linkonce.t.*)
  220 + /* .gnu.warning sections are handled specially by elf32.em. */
  221 + *(.gnu.warning)
  222 + } =0x90909090
  223 + .fini :
  224 + {
  225 + KEEP (*(.fini))
  226 + } =0x90909090
  227 + PROVIDE (__etext = .);
  228 + PROVIDE (_etext = .);
  229 + PROVIDE (etext = .);
  230 + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
  231 + .rodata1 : { *(.rodata1) }
  232 + .eh_frame_hdr : { *(.eh_frame_hdr) }
  233 + .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
  234 + .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table) }
  235 + /* Adjust the address for the data segment. We want to adjust up to
  236 + the same address within the page on the next page up. */
  237 + . = ALIGN (0x100000) - ((0x100000 - .) & (0x100000 - 1)); . = DATA_SEGMENT_ALIGN (0x100000, 0x1000);
  238 + /* Ensure the __preinit_array_start label is properly aligned. We
  239 + could instead move the label definition inside the section, but
  240 + the linker would then create the section even if it turns out to
  241 + be empty, which isn't pretty. */
  242 + . = ALIGN(64 / 8);
  243 + PROVIDE (__preinit_array_start = .);
  244 + .preinit_array : { *(.preinit_array) }
  245 + PROVIDE (__preinit_array_end = .);
  246 + PROVIDE (__init_array_start = .);
  247 + .init_array : { *(.init_array) }
  248 + PROVIDE (__init_array_end = .);
  249 + PROVIDE (__fini_array_start = .);
  250 + .fini_array : { *(.fini_array) }
  251 + PROVIDE (__fini_array_end = .);
  252 + .data :
  253 + {
  254 + *(.data .data.* .gnu.linkonce.d.*)
  255 + SORT(CONSTRUCTORS)
  256 + }
  257 + .data1 : { *(.data1) }
  258 + .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
  259 + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
  260 + .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }
  261 + .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table) }
  262 + .dynamic : { *(.dynamic) }
  263 + .ctors :
  264 + {
  265 + /* gcc uses crtbegin.o to find the start of
  266 + the constructors, so we make sure it is
  267 + first. Because this is a wildcard, it
  268 + doesn't matter if the user does not
  269 + actually link against crtbegin.o; the
  270 + linker won't look for a file to match a
  271 + wildcard. The wildcard also means that it
  272 + doesn't matter which directory crtbegin.o
  273 + is in. */
  274 + KEEP (*crtbegin.o(.ctors))
  275 + /* We don't want to include the .ctor section from
  276 + from the crtend.o file until after the sorted ctors.
  277 + The .ctor section from the crtend file contains the
  278 + end of ctors marker and it must be last */
  279 + KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors))
  280 + KEEP (*(SORT(.ctors.*)))
  281 + KEEP (*(.ctors))
  282 + }
  283 + .dtors :
  284 + {
  285 + KEEP (*crtbegin.o(.dtors))
  286 + KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))
  287 + KEEP (*(SORT(.dtors.*)))
  288 + KEEP (*(.dtors))
  289 + }
  290 + .jcr : { KEEP (*(.jcr)) }
  291 + .got : { *(.got.plt) *(.got) }
  292 + _edata = .;
  293 + PROVIDE (edata = .);
  294 + __bss_start = .;
  295 + .bss :
  296 + {
  297 + *(.dynbss)
  298 + *(.bss .bss.* .gnu.linkonce.b.*)
  299 + *(COMMON)
  300 + /* Align here to ensure that the .bss section occupies space up to
  301 + _end. Align after .bss to ensure correct alignment even if the
  302 + .bss section disappears because there are no input sections. */
  303 + . = ALIGN(64 / 8);
  304 + }
  305 + . = ALIGN(64 / 8);
  306 + _end = .;
  307 + PROVIDE (end = .);
  308 + . = DATA_SEGMENT_END (.);
  309 + /* Stabs debugging sections. */
  310 + .stab 0 : { *(.stab) }
  311 + .stabstr 0 : { *(.stabstr) }
  312 + .stab.excl 0 : { *(.stab.excl) }
  313 + .stab.exclstr 0 : { *(.stab.exclstr) }
  314 + .stab.index 0 : { *(.stab.index) }
  315 + .stab.indexstr 0 : { *(.stab.indexstr) }
  316 + .comment 0 : { *(.comment) }
  317 + /* DWARF debug sections.
  318 + Symbols in the DWARF debugging sections are relative to the beginning
  319 + of the section so we begin them at 0. */
  320 + /* DWARF 1 */
  321 + .debug 0 : { *(.debug) }
  322 + .line 0 : { *(.line) }
  323 + /* GNU DWARF 1 extensions */
  324 + .debug_srcinfo 0 : { *(.debug_srcinfo) }
  325 + .debug_sfnames 0 : { *(.debug_sfnames) }
  326 + /* DWARF 1.1 and DWARF 2 */
  327 + .debug_aranges 0 : { *(.debug_aranges) }
  328 + .debug_pubnames 0 : { *(.debug_pubnames) }
  329 + /* DWARF 2 */
  330 + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
  331 + .debug_abbrev 0 : { *(.debug_abbrev) }
  332 + .debug_line 0 : { *(.debug_line) }
  333 + .debug_frame 0 : { *(.debug_frame) }
  334 + .debug_str 0 : { *(.debug_str) }
  335 + .debug_loc 0 : { *(.debug_loc) }
  336 + .debug_macinfo 0 : { *(.debug_macinfo) }
  337 + /* SGI/MIPS DWARF 2 extensions */
  338 + .debug_weaknames 0 : { *(.debug_weaknames) }
  339 + .debug_funcnames 0 : { *(.debug_funcnames) }
  340 + .debug_typenames 0 : { *(.debug_typenames) }
  341 + .debug_varnames 0 : { *(.debug_varnames) }
  342 +}
... ...
... ... @@ -43,7 +43,7 @@
43 43  
44 44 #endif /* !HAVE_BYTESWAP_H */
45 45  
46   -#if defined(__alpha__) || defined (__ia64__)
  46 +#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
47 47 #define HOST_LONG_BITS 64
48 48 #else
49 49 #define HOST_LONG_BITS 32
... ...
configure
... ... @@ -59,6 +59,9 @@ case "$cpu" in
59 59 m68k)
60 60 cpu="m68k"
61 61 ;;
  62 + x86_64|amd64)
  63 + cpu="amd64"
  64 + ;;
62 65 *)
63 66 cpu="unknown"
64 67 ;;
... ... @@ -253,6 +256,9 @@ echo "LDFLAGS=$LDFLAGS" >> $config_mak
253 256 if test "$cpu" = "i386" ; then
254 257 echo "ARCH=i386" >> $config_mak
255 258 echo "#define HOST_I386 1" >> $config_h
  259 +elif test "$cpu" = "amd64" ; then
  260 + echo "ARCH=amd64" >> $config_mak
  261 + echo "#define HOST_AMD64 1" >> $config_h
256 262 elif test "$cpu" = "armv4l" ; then
257 263 echo "ARCH=arm" >> $config_mak
258 264 echo "#define HOST_ARM 1" >> $config_h
... ...
cpu-exec.c
... ... @@ -785,6 +785,21 @@ int cpu_signal_handler(int host_signum, struct siginfo *info,
785 785 &uc->uc_sigmask, puc);
786 786 }
787 787  
  788 +#elif defined(__x86_64__)
  789 +
  790 +int cpu_signal_handler(int host_signum, struct siginfo *info,
  791 + void *puc)
  792 +{
  793 + struct ucontext *uc = puc;
  794 + unsigned long pc;
  795 +
  796 + pc = uc->uc_mcontext.gregs[REG_RIP];
  797 + return handle_cpu_signal(pc, (unsigned long)info->si_addr,
  798 + uc->uc_mcontext.gregs[REG_TRAPNO] == 0xe ?
  799 + (uc->uc_mcontext.gregs[REG_ERR] >> 1) & 1 : 0,
  800 + &uc->uc_sigmask, puc);
  801 +}
  802 +
788 803 #elif defined(__powerpc)
789 804  
790 805 int cpu_signal_handler(int host_signum, struct siginfo *info,
... ...
dis-asm.h
... ... @@ -16,7 +16,9 @@
16 16 #define PARAMS(x) x
17 17 typedef void *PTR;
18 18 typedef uint64_t bfd_vma;
  19 +typedef int64_t bfd_signed_vma;
19 20 typedef uint8_t bfd_byte;
  21 +#define sprintf_vma(s,x) sprintf (s, "%0" PRIx64, x)
20 22  
21 23 enum bfd_flavour {
22 24 bfd_target_unknown_flavour,
... ... @@ -105,6 +107,9 @@ enum bfd_architecture
105 107 bfd_arch_i386, /* Intel 386 */
106 108 #define bfd_mach_i386_i386 0
107 109 #define bfd_mach_i386_i8086 1
  110 +#define bfd_mach_i386_i386_intel_syntax 2
  111 +#define bfd_mach_x86_64 3
  112 +#define bfd_mach_x86_64_intel_syntax 4
108 113 bfd_arch_we32k, /* AT&T WE32xxx */
109 114 bfd_arch_tahoe, /* CCI/Harris Tahoe */
110 115 bfd_arch_i860, /* Intel 860 */
... ...
... ... @@ -140,9 +140,12 @@ void disas(FILE *out, void *code, unsigned long size, int is_host, int flags)
140 140 #else
141 141 disasm_info.endian = BFD_ENDIAN_LITTLE;
142 142 #endif
143   -#ifdef __i386__
  143 +#if defined(__i386__)
144 144 disasm_info.mach = bfd_mach_i386_i386;
145 145 print_insn = print_insn_i386;
  146 +#elif defined(__x86_64__)
  147 + disasm_info.mach = bfd_mach_x86_64;
  148 + print_insn = print_insn_i386;
146 149 #elif defined(__powerpc__)
147 150 print_insn = print_insn_ppc;
148 151 #elif defined(__alpha__)
... ...
dyngen-exec.h
... ... @@ -68,6 +68,14 @@ extern int printf(const char *, ...);
68 68 #define AREG2 "esi"
69 69 #define AREG3 "edi"
70 70 #endif
  71 +#ifdef __x86_64__
  72 +#define AREG0 "rbp"
  73 +#define AREG1 "rbx"
  74 +#define AREG2 "r12"
  75 +#define AREG3 "r13"
  76 +#define AREG4 "r14"
  77 +#define AREG5 "r15"
  78 +#endif
71 79 #ifdef __powerpc__
72 80 #define AREG0 "r27"
73 81 #define AREG1 "r24"
... ... @@ -188,6 +196,9 @@ extern int __op_jmp0, __op_jmp1, __op_jmp2, __op_jmp3;
188 196 #ifdef __i386__
189 197 #define EXIT_TB() asm volatile ("ret")
190 198 #endif
  199 +#ifdef __x86_64__
  200 +#define EXIT_TB() asm volatile ("ret")
  201 +#endif
191 202 #ifdef __powerpc__
192 203 #define EXIT_TB() asm volatile ("blr")
193 204 #endif
... ...
dyngen.c
... ... @@ -37,6 +37,13 @@
37 37 #define elf_check_arch(x) ( ((x) == EM_386) || ((x) == EM_486) )
38 38 #undef ELF_USES_RELOCA
39 39  
  40 +#elif defined(HOST_AMD64)
  41 +
  42 +#define ELF_CLASS ELFCLASS64
  43 +#define ELF_ARCH EM_X86_64
  44 +#define elf_check_arch(x) ((x) == EM_X86_64)
  45 +#define ELF_USES_RELOCA
  46 +
40 47 #elif defined(HOST_PPC)
41 48  
42 49 #define ELF_CLASS ELFCLASS32
... ... @@ -446,6 +453,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
446 453 start_offset = offset;
447 454 switch(ELF_ARCH) {
448 455 case EM_386:
  456 + case EM_X86_64:
449 457 {
450 458 int len;
451 459 len = p_end - p_start;
... ... @@ -766,6 +774,41 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
766 774 }
767 775 }
768 776 }
  777 +#elif defined(HOST_AMD64)
  778 + {
  779 + char name[256];
  780 + int type;
  781 + int addend;
  782 + for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
  783 + if (rel->r_offset >= start_offset &&
  784 + rel->r_offset < start_offset + copy_size) {
  785 + sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
  786 + if (strstart(sym_name, "__op_param", &p)) {
  787 + snprintf(name, sizeof(name), "param%s", p);
  788 + } else {
  789 + snprintf(name, sizeof(name), "(long)(&%s)", sym_name);
  790 + }
  791 + type = ELF32_R_TYPE(rel->r_info);
  792 + addend = rel->r_addend;
  793 + switch(type) {
  794 + case R_X86_64_32:
  795 + fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = (uint32_t)%s + %d;\n",
  796 + rel->r_offset - start_offset, name, addend);
  797 + break;
  798 + case R_X86_64_32S:
  799 + fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = (int32_t)%s + %d;\n",
  800 + rel->r_offset - start_offset, name, addend);
  801 + break;
  802 + case R_X86_64_PC32:
  803 + fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %d) + %d;\n",
  804 + rel->r_offset - start_offset, name, rel->r_offset - start_offset, addend);
  805 + break;
  806 + default:
  807 + error("unsupported AMD64 relocation (%d)", type);
  808 + }
  809 + }
  810 + }
  811 + }
769 812 #elif defined(HOST_PPC)
770 813 {
771 814 char name[256];
... ...
dyngen.h
... ... @@ -27,6 +27,12 @@ static inline void flush_icache_range(unsigned long start, unsigned long stop)
27 27 }
28 28 #endif
29 29  
  30 +#ifdef __x86_64__
  31 +static inline void flush_icache_range(unsigned long start, unsigned long stop)
  32 +{
  33 +}
  34 +#endif
  35 +
30 36 #ifdef __s390__
31 37 static inline void flush_icache_range(unsigned long start, unsigned long stop)
32 38 {
... ...
exec-all.h
... ... @@ -400,6 +400,20 @@ static inline int testandset (int *p)
400 400 }
401 401 #endif
402 402  
  403 +#ifdef __x86_64__
  404 +static inline int testandset (int *p)
  405 +{
  406 + char ret;
  407 + int readval;
  408 +
  409 + __asm__ __volatile__ ("lock; cmpxchgl %3, %1; sete %0"
  410 + : "=q" (ret), "=m" (*p), "=a" (readval)
  411 + : "r" (1), "m" (*p), "a" (0)
  412 + : "memory");
  413 + return ret;
  414 +}
  415 +#endif
  416 +
403 417 #ifdef __s390__
404 418 static inline int testandset (int *p)
405 419 {
... ...