Commit bc51c5c989c12b3936b78c5772a3308629a7484c
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
Showing
12 changed files
with
459 additions
and
2 deletions
Too many changes to show.
To preserve performance only 12 of 17 files are displayed.
Changelog
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 | +} | ... | ... |
bswap.h
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 */ | ... | ... |
disas.c
| ... | ... | @@ -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 | { | ... | ... |