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 | { | ... | ... |