Revision 84409ddb
b/linux-user/elfload.c | ||
---|---|---|
44 | 44 |
return global_env->cpuid_features; |
45 | 45 |
} |
46 | 46 |
|
47 |
#ifdef TARGET_X86_64 |
|
48 |
#define ELF_START_MMAP 0x2aaaaab000ULL |
|
49 |
#define elf_check_arch(x) ( ((x) == ELF_ARCH) ) |
|
50 |
|
|
51 |
#define ELF_CLASS ELFCLASS64 |
|
52 |
#define ELF_DATA ELFDATA2LSB |
|
53 |
#define ELF_ARCH EM_X86_64 |
|
54 |
|
|
55 |
static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) |
|
56 |
{ |
|
57 |
regs->rax = 0; |
|
58 |
regs->rsp = infop->start_stack; |
|
59 |
regs->rip = infop->entry; |
|
60 |
} |
|
61 |
|
|
62 |
#else |
|
63 |
|
|
47 | 64 |
#define ELF_START_MMAP 0x80000000 |
48 | 65 |
|
49 | 66 |
/* |
... | ... | |
72 | 89 |
A value of 0 tells we have no such handler. */ |
73 | 90 |
regs->edx = 0; |
74 | 91 |
} |
92 |
#endif |
|
75 | 93 |
|
76 | 94 |
#define USE_ELF_CORE_DUMP |
77 | 95 |
#define ELF_EXEC_PAGESIZE 4096 |
... | ... | |
177 | 195 |
|
178 | 196 |
#define ELF_START_MMAP 0x80000000 |
179 | 197 |
|
198 |
#ifdef TARGET_PPC64 |
|
199 |
|
|
200 |
#define elf_check_arch(x) ( (x) == EM_PPC64 ) |
|
201 |
|
|
202 |
#define ELF_CLASS ELFCLASS64 |
|
203 |
|
|
204 |
#else |
|
205 |
|
|
180 | 206 |
#define elf_check_arch(x) ( (x) == EM_PPC ) |
181 | 207 |
|
182 | 208 |
#define ELF_CLASS ELFCLASS32 |
209 |
|
|
210 |
#endif |
|
211 |
|
|
183 | 212 |
#ifdef TARGET_WORDS_BIGENDIAN |
184 | 213 |
#define ELF_DATA ELFDATA2MSB |
185 | 214 |
#else |
... | ... | |
222 | 251 |
{ |
223 | 252 |
target_ulong pos = infop->start_stack; |
224 | 253 |
target_ulong tmp; |
254 |
#ifdef TARGET_PPC64 |
|
255 |
target_ulong entry, toc; |
|
256 |
#endif |
|
225 | 257 |
|
226 | 258 |
_regs->msr = 1 << MSR_PR; /* Set user mode */ |
227 | 259 |
_regs->gpr[1] = infop->start_stack; |
260 |
#ifdef TARGET_PPC64 |
|
261 |
entry = ldq_raw(infop->entry) + infop->load_addr; |
|
262 |
toc = ldq_raw(infop->entry + 8) + infop->load_addr; |
|
263 |
_regs->gpr[2] = toc; |
|
264 |
infop->entry = entry; |
|
265 |
#endif |
|
228 | 266 |
_regs->nip = infop->entry; |
229 | 267 |
/* Note that isn't exactly what regular kernel does |
230 | 268 |
* but this is what the ABI wants and is needed to allow |
... | ... | |
917 | 955 |
unsigned long elf_entry, interp_load_addr = 0; |
918 | 956 |
int status; |
919 | 957 |
unsigned long start_code, end_code, end_data; |
958 |
unsigned long reloc_func_desc = 0; |
|
920 | 959 |
unsigned long elf_stack; |
921 | 960 |
char passed_fileno[6]; |
922 | 961 |
|
... | ... | |
1181 | 1220 |
load_bias += error - |
1182 | 1221 |
TARGET_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr); |
1183 | 1222 |
load_addr += load_bias; |
1223 |
reloc_func_desc = load_bias; |
|
1184 | 1224 |
} |
1185 | 1225 |
} |
1186 | 1226 |
k = elf_ppnt->p_vaddr; |
... | ... | |
1213 | 1253 |
elf_entry = load_elf_interp(&interp_elf_ex, interpreter_fd, |
1214 | 1254 |
&interp_load_addr); |
1215 | 1255 |
} |
1256 |
reloc_func_desc = interp_load_addr; |
|
1216 | 1257 |
|
1217 | 1258 |
close(interpreter_fd); |
1218 | 1259 |
free(elf_interpreter); |
b/linux-user/main.c | ||
---|---|---|
194 | 194 |
queue_signal(info.si_signo, &info); |
195 | 195 |
break; |
196 | 196 |
case EXCP0D_GPF: |
197 |
#ifndef TARGET_X86_64 |
|
197 | 198 |
if (env->eflags & VM_MASK) { |
198 | 199 |
handle_vm86_fault(env); |
199 |
} else { |
|
200 |
} else |
|
201 |
#endif |
|
202 |
{ |
|
200 | 203 |
info.si_signo = SIGSEGV; |
201 | 204 |
info.si_errno = 0; |
202 | 205 |
info.si_code = TARGET_SI_KERNEL; |
... | ... | |
215 | 218 |
queue_signal(info.si_signo, &info); |
216 | 219 |
break; |
217 | 220 |
case EXCP00_DIVZ: |
221 |
#ifndef TARGET_X86_64 |
|
218 | 222 |
if (env->eflags & VM_MASK) { |
219 | 223 |
handle_vm86_trap(env, trapnr); |
220 |
} else { |
|
224 |
} else |
|
225 |
#endif |
|
226 |
{ |
|
221 | 227 |
/* division by zero */ |
222 | 228 |
info.si_signo = SIGFPE; |
223 | 229 |
info.si_errno = 0; |
... | ... | |
228 | 234 |
break; |
229 | 235 |
case EXCP01_SSTP: |
230 | 236 |
case EXCP03_INT3: |
237 |
#ifndef TARGET_X86_64 |
|
231 | 238 |
if (env->eflags & VM_MASK) { |
232 | 239 |
handle_vm86_trap(env, trapnr); |
233 |
} else { |
|
240 |
} else |
|
241 |
#endif |
|
242 |
{ |
|
234 | 243 |
info.si_signo = SIGTRAP; |
235 | 244 |
info.si_errno = 0; |
236 | 245 |
if (trapnr == EXCP01_SSTP) { |
... | ... | |
245 | 254 |
break; |
246 | 255 |
case EXCP04_INTO: |
247 | 256 |
case EXCP05_BOUND: |
257 |
#ifndef TARGET_X86_64 |
|
248 | 258 |
if (env->eflags & VM_MASK) { |
249 | 259 |
handle_vm86_trap(env, trapnr); |
250 |
} else { |
|
260 |
} else |
|
261 |
#endif |
|
262 |
{ |
|
251 | 263 |
info.si_signo = SIGSEGV; |
252 | 264 |
info.si_errno = 0; |
253 | 265 |
info.si_code = TARGET_SI_KERNEL; |
... | ... | |
1807 | 1819 |
env->eflags |= IF_MASK; |
1808 | 1820 |
|
1809 | 1821 |
/* linux register setup */ |
1822 |
#if defined(TARGET_X86_64) |
|
1823 |
env->regs[R_EAX] = regs->rax; |
|
1824 |
env->regs[R_EBX] = regs->rbx; |
|
1825 |
env->regs[R_ECX] = regs->rcx; |
|
1826 |
env->regs[R_EDX] = regs->rdx; |
|
1827 |
env->regs[R_ESI] = regs->rsi; |
|
1828 |
env->regs[R_EDI] = regs->rdi; |
|
1829 |
env->regs[R_EBP] = regs->rbp; |
|
1830 |
env->regs[R_ESP] = regs->rsp; |
|
1831 |
env->eip = regs->rip; |
|
1832 |
#else |
|
1810 | 1833 |
env->regs[R_EAX] = regs->eax; |
1811 | 1834 |
env->regs[R_EBX] = regs->ebx; |
1812 | 1835 |
env->regs[R_ECX] = regs->ecx; |
... | ... | |
1816 | 1839 |
env->regs[R_EBP] = regs->ebp; |
1817 | 1840 |
env->regs[R_ESP] = regs->esp; |
1818 | 1841 |
env->eip = regs->eip; |
1842 |
#endif |
|
1819 | 1843 |
|
1820 | 1844 |
/* linux interrupt setup */ |
1821 | 1845 |
env->idt.base = h2g(idt_table); |
... | ... | |
1903 | 1927 |
if (i != 12 && i != 6 && i != 13) |
1904 | 1928 |
env->msr[i] = (regs->msr >> i) & 1; |
1905 | 1929 |
} |
1930 |
#if defined(TARGET_PPC64) |
|
1931 |
msr_sf = 1; |
|
1932 |
#endif |
|
1906 | 1933 |
env->nip = regs->nip; |
1907 | 1934 |
for(i = 0; i < 32; i++) { |
1908 | 1935 |
env->gpr[i] = regs->gpr[i]; |
b/linux-user/qemu.h | ||
---|---|---|
68 | 68 |
uint32_t heap_limit; |
69 | 69 |
int swi_errno; |
70 | 70 |
#endif |
71 |
#ifdef TARGET_I386
|
|
71 |
#if defined(TARGET_I386) && !defined(TARGET_X86_64)
|
|
72 | 72 |
target_ulong target_v86; |
73 | 73 |
struct vm86_saved_state vm86_saved_regs; |
74 | 74 |
struct target_vm86plus_struct vm86plus; |
b/linux-user/signal.c | ||
---|---|---|
690 | 690 |
err |= __put_user(frame->retcode, &frame->pretcode); |
691 | 691 |
/* This is popl %eax ; movl $,%eax ; int $0x80 */ |
692 | 692 |
err |= __put_user(0xb858, (short *)(frame->retcode+0)); |
693 |
#if defined(TARGET_X86_64) |
|
694 |
#warning "Fix this !" |
|
695 |
#else |
|
693 | 696 |
err |= __put_user(TARGET_NR_sigreturn, (int *)(frame->retcode+2)); |
697 |
#endif |
|
694 | 698 |
err |= __put_user(0x80cd, (short *)(frame->retcode+6)); |
695 | 699 |
} |
696 | 700 |
|
... | ... | |
2048 | 2052 |
host_to_target_sigset_internal(&target_old_set, &old_set); |
2049 | 2053 |
|
2050 | 2054 |
/* if the CPU is in VM86 mode, we restore the 32 bit values */ |
2051 |
#ifdef TARGET_I386
|
|
2055 |
#if defined(TARGET_I386) && !defined(TARGET_X86_64)
|
|
2052 | 2056 |
{ |
2053 | 2057 |
CPUX86State *env = cpu_env; |
2054 | 2058 |
if (env->eflags & VM_MASK) |
b/linux-user/syscall.c | ||
---|---|---|
3250 | 3250 |
case TARGET_NR_modify_ldt: |
3251 | 3251 |
ret = get_errno(do_modify_ldt(cpu_env, arg1, arg2, arg3)); |
3252 | 3252 |
break; |
3253 |
#if !defined(TARGET_X86_64) |
|
3253 | 3254 |
case TARGET_NR_vm86old: |
3254 | 3255 |
goto unimplemented; |
3255 | 3256 |
case TARGET_NR_vm86: |
3256 | 3257 |
ret = do_vm86(cpu_env, arg1, arg2); |
3257 | 3258 |
break; |
3258 | 3259 |
#endif |
3260 |
#endif |
|
3259 | 3261 |
case TARGET_NR_adjtimex: |
3260 | 3262 |
goto unimplemented; |
3261 | 3263 |
#ifdef TARGET_NR_create_module |
... | ... | |
3275 | 3277 |
case TARGET_NR_fchdir: |
3276 | 3278 |
ret = get_errno(fchdir(arg1)); |
3277 | 3279 |
break; |
3280 |
#ifdef TARGET_NR_bdflush /* not on x86_64 */ |
|
3278 | 3281 |
case TARGET_NR_bdflush: |
3279 | 3282 |
goto unimplemented; |
3283 |
#endif |
|
3280 | 3284 |
#ifdef TARGET_NR_sysfs |
3281 | 3285 |
case TARGET_NR_sysfs: |
3282 | 3286 |
goto unimplemented; |
Also available in: Unified diff