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
| @@ -18,6 +18,7 @@ version 0.5.3: | @@ -18,6 +18,7 @@ version 0.5.3: | ||
| 18 | - generic removable device support | 18 | - generic removable device support |
| 19 | - support of CD-ROM change | 19 | - support of CD-ROM change |
| 20 | - multiple network interface support | 20 | - multiple network interface support |
| 21 | + - initial x86-64 host support (Gwenole Beauchesne) | ||
| 21 | 22 | ||
| 22 | version 0.5.2: | 23 | version 0.5.2: |
| 23 | 24 |
Makefile.target
| @@ -80,6 +80,11 @@ LDFLAGS+=-Wl,-shared | @@ -80,6 +80,11 @@ LDFLAGS+=-Wl,-shared | ||
| 80 | endif | 80 | endif |
| 81 | endif | 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 | ifeq ($(ARCH),ppc) | 88 | ifeq ($(ARCH),ppc) |
| 84 | OP_CFLAGS=$(CFLAGS) | 89 | OP_CFLAGS=$(CFLAGS) |
| 85 | LDFLAGS+=-Wl,-T,$(SRC_PATH)/ppc.ld | 90 | LDFLAGS+=-Wl,-T,$(SRC_PATH)/ppc.ld |
| @@ -174,6 +179,12 @@ endif | @@ -174,6 +179,12 @@ endif | ||
| 174 | # NOTE: the disassembler code is only needed for debugging | 179 | # NOTE: the disassembler code is only needed for debugging |
| 175 | LIBOBJS+=disas.o | 180 | LIBOBJS+=disas.o |
| 176 | ifeq ($(findstring i386, $(TARGET_ARCH) $(ARCH)),i386) | 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 | LIBOBJS+=i386-dis.o | 188 | LIBOBJS+=i386-dis.o |
| 178 | endif | 189 | endif |
| 179 | ifeq ($(findstring alpha, $(TARGET_ARCH) $(ARCH)),alpha) | 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
| @@ -43,7 +43,7 @@ | @@ -43,7 +43,7 @@ | ||
| 43 | 43 | ||
| 44 | #endif /* !HAVE_BYTESWAP_H */ | 44 | #endif /* !HAVE_BYTESWAP_H */ |
| 45 | 45 | ||
| 46 | -#if defined(__alpha__) || defined (__ia64__) | 46 | +#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__) |
| 47 | #define HOST_LONG_BITS 64 | 47 | #define HOST_LONG_BITS 64 |
| 48 | #else | 48 | #else |
| 49 | #define HOST_LONG_BITS 32 | 49 | #define HOST_LONG_BITS 32 |
configure
| @@ -59,6 +59,9 @@ case "$cpu" in | @@ -59,6 +59,9 @@ case "$cpu" in | ||
| 59 | m68k) | 59 | m68k) |
| 60 | cpu="m68k" | 60 | cpu="m68k" |
| 61 | ;; | 61 | ;; |
| 62 | + x86_64|amd64) | ||
| 63 | + cpu="amd64" | ||
| 64 | + ;; | ||
| 62 | *) | 65 | *) |
| 63 | cpu="unknown" | 66 | cpu="unknown" |
| 64 | ;; | 67 | ;; |
| @@ -253,6 +256,9 @@ echo "LDFLAGS=$LDFLAGS" >> $config_mak | @@ -253,6 +256,9 @@ echo "LDFLAGS=$LDFLAGS" >> $config_mak | ||
| 253 | if test "$cpu" = "i386" ; then | 256 | if test "$cpu" = "i386" ; then |
| 254 | echo "ARCH=i386" >> $config_mak | 257 | echo "ARCH=i386" >> $config_mak |
| 255 | echo "#define HOST_I386 1" >> $config_h | 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 | elif test "$cpu" = "armv4l" ; then | 262 | elif test "$cpu" = "armv4l" ; then |
| 257 | echo "ARCH=arm" >> $config_mak | 263 | echo "ARCH=arm" >> $config_mak |
| 258 | echo "#define HOST_ARM 1" >> $config_h | 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,6 +785,21 @@ int cpu_signal_handler(int host_signum, struct siginfo *info, | ||
| 785 | &uc->uc_sigmask, puc); | 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 | #elif defined(__powerpc) | 803 | #elif defined(__powerpc) |
| 789 | 804 | ||
| 790 | int cpu_signal_handler(int host_signum, struct siginfo *info, | 805 | int cpu_signal_handler(int host_signum, struct siginfo *info, |
dis-asm.h
| @@ -16,7 +16,9 @@ | @@ -16,7 +16,9 @@ | ||
| 16 | #define PARAMS(x) x | 16 | #define PARAMS(x) x |
| 17 | typedef void *PTR; | 17 | typedef void *PTR; |
| 18 | typedef uint64_t bfd_vma; | 18 | typedef uint64_t bfd_vma; |
| 19 | +typedef int64_t bfd_signed_vma; | ||
| 19 | typedef uint8_t bfd_byte; | 20 | typedef uint8_t bfd_byte; |
| 21 | +#define sprintf_vma(s,x) sprintf (s, "%0" PRIx64, x) | ||
| 20 | 22 | ||
| 21 | enum bfd_flavour { | 23 | enum bfd_flavour { |
| 22 | bfd_target_unknown_flavour, | 24 | bfd_target_unknown_flavour, |
| @@ -105,6 +107,9 @@ enum bfd_architecture | @@ -105,6 +107,9 @@ enum bfd_architecture | ||
| 105 | bfd_arch_i386, /* Intel 386 */ | 107 | bfd_arch_i386, /* Intel 386 */ |
| 106 | #define bfd_mach_i386_i386 0 | 108 | #define bfd_mach_i386_i386 0 |
| 107 | #define bfd_mach_i386_i8086 1 | 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 | bfd_arch_we32k, /* AT&T WE32xxx */ | 113 | bfd_arch_we32k, /* AT&T WE32xxx */ |
| 109 | bfd_arch_tahoe, /* CCI/Harris Tahoe */ | 114 | bfd_arch_tahoe, /* CCI/Harris Tahoe */ |
| 110 | bfd_arch_i860, /* Intel 860 */ | 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,9 +140,12 @@ void disas(FILE *out, void *code, unsigned long size, int is_host, int flags) | ||
| 140 | #else | 140 | #else |
| 141 | disasm_info.endian = BFD_ENDIAN_LITTLE; | 141 | disasm_info.endian = BFD_ENDIAN_LITTLE; |
| 142 | #endif | 142 | #endif |
| 143 | -#ifdef __i386__ | 143 | +#if defined(__i386__) |
| 144 | disasm_info.mach = bfd_mach_i386_i386; | 144 | disasm_info.mach = bfd_mach_i386_i386; |
| 145 | print_insn = print_insn_i386; | 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 | #elif defined(__powerpc__) | 149 | #elif defined(__powerpc__) |
| 147 | print_insn = print_insn_ppc; | 150 | print_insn = print_insn_ppc; |
| 148 | #elif defined(__alpha__) | 151 | #elif defined(__alpha__) |
dyngen-exec.h
| @@ -68,6 +68,14 @@ extern int printf(const char *, ...); | @@ -68,6 +68,14 @@ extern int printf(const char *, ...); | ||
| 68 | #define AREG2 "esi" | 68 | #define AREG2 "esi" |
| 69 | #define AREG3 "edi" | 69 | #define AREG3 "edi" |
| 70 | #endif | 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 | #ifdef __powerpc__ | 79 | #ifdef __powerpc__ |
| 72 | #define AREG0 "r27" | 80 | #define AREG0 "r27" |
| 73 | #define AREG1 "r24" | 81 | #define AREG1 "r24" |
| @@ -188,6 +196,9 @@ extern int __op_jmp0, __op_jmp1, __op_jmp2, __op_jmp3; | @@ -188,6 +196,9 @@ extern int __op_jmp0, __op_jmp1, __op_jmp2, __op_jmp3; | ||
| 188 | #ifdef __i386__ | 196 | #ifdef __i386__ |
| 189 | #define EXIT_TB() asm volatile ("ret") | 197 | #define EXIT_TB() asm volatile ("ret") |
| 190 | #endif | 198 | #endif |
| 199 | +#ifdef __x86_64__ | ||
| 200 | +#define EXIT_TB() asm volatile ("ret") | ||
| 201 | +#endif | ||
| 191 | #ifdef __powerpc__ | 202 | #ifdef __powerpc__ |
| 192 | #define EXIT_TB() asm volatile ("blr") | 203 | #define EXIT_TB() asm volatile ("blr") |
| 193 | #endif | 204 | #endif |
dyngen.c
| @@ -37,6 +37,13 @@ | @@ -37,6 +37,13 @@ | ||
| 37 | #define elf_check_arch(x) ( ((x) == EM_386) || ((x) == EM_486) ) | 37 | #define elf_check_arch(x) ( ((x) == EM_386) || ((x) == EM_486) ) |
| 38 | #undef ELF_USES_RELOCA | 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 | #elif defined(HOST_PPC) | 47 | #elif defined(HOST_PPC) |
| 41 | 48 | ||
| 42 | #define ELF_CLASS ELFCLASS32 | 49 | #define ELF_CLASS ELFCLASS32 |
| @@ -446,6 +453,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, | @@ -446,6 +453,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, | ||
| 446 | start_offset = offset; | 453 | start_offset = offset; |
| 447 | switch(ELF_ARCH) { | 454 | switch(ELF_ARCH) { |
| 448 | case EM_386: | 455 | case EM_386: |
| 456 | + case EM_X86_64: | ||
| 449 | { | 457 | { |
| 450 | int len; | 458 | int len; |
| 451 | len = p_end - p_start; | 459 | len = p_end - p_start; |
| @@ -766,6 +774,41 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, | @@ -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 | #elif defined(HOST_PPC) | 812 | #elif defined(HOST_PPC) |
| 770 | { | 813 | { |
| 771 | char name[256]; | 814 | char name[256]; |
dyngen.h
| @@ -27,6 +27,12 @@ static inline void flush_icache_range(unsigned long start, unsigned long stop) | @@ -27,6 +27,12 @@ static inline void flush_icache_range(unsigned long start, unsigned long stop) | ||
| 27 | } | 27 | } |
| 28 | #endif | 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 | #ifdef __s390__ | 36 | #ifdef __s390__ |
| 31 | static inline void flush_icache_range(unsigned long start, unsigned long stop) | 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,6 +400,20 @@ static inline int testandset (int *p) | ||
| 400 | } | 400 | } |
| 401 | #endif | 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 | #ifdef __s390__ | 417 | #ifdef __s390__ |
| 404 | static inline int testandset (int *p) | 418 | static inline int testandset (int *p) |
| 405 | { | 419 | { |