Commit 7a3148a955e3350720a01f57163ab230b72aca7e
1 parent
86cc1ce0
Preliminary patch for Alpha Linux user mode emulation support.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2600 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
212 additions
and
5 deletions
linux-user/elfload.c
... | ... | @@ -313,6 +313,31 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i |
313 | 313 | |
314 | 314 | #endif |
315 | 315 | |
316 | +#ifdef TARGET_ALPHA | |
317 | + | |
318 | +#define ELF_START_MMAP (0x30000000000ULL) | |
319 | + | |
320 | +#define elf_check_arch(x) ( (x) == ELF_ARCH ) | |
321 | + | |
322 | +#define ELF_CLASS ELFCLASS64 | |
323 | +#define ELF_DATA ELFDATA2MSB | |
324 | +#define ELF_ARCH EM_ALPHA | |
325 | + | |
326 | +static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) | |
327 | +{ | |
328 | + regs->pc = infop->entry; | |
329 | + regs->ps = 8; | |
330 | + regs->usp = infop->start_stack; | |
331 | + regs->unique = infop->start_data; /* ? */ | |
332 | + printf("Set unique value to " TARGET_FMT_lx " (" TARGET_FMT_lx ")\n", | |
333 | + regs->unique, infop->start_data); | |
334 | +} | |
335 | + | |
336 | +#define USE_ELF_CORE_DUMP | |
337 | +#define ELF_EXEC_PAGESIZE 8192 | |
338 | + | |
339 | +#endif /* TARGET_ALPHA */ | |
340 | + | |
316 | 341 | #ifndef ELF_PLATFORM |
317 | 342 | #define ELF_PLATFORM (NULL) |
318 | 343 | #endif |
... | ... | @@ -431,11 +456,11 @@ static void bswap_shdr(struct elf_shdr *shdr) |
431 | 456 | bswaptls(&shdr->sh_entsize); |
432 | 457 | } |
433 | 458 | |
434 | -static void bswap_sym(Elf32_Sym *sym) | |
459 | +static void bswap_sym(struct elf_sym *sym) | |
435 | 460 | { |
436 | 461 | bswap32s(&sym->st_name); |
437 | - bswap32s(&sym->st_value); | |
438 | - bswap32s(&sym->st_size); | |
462 | + bswaptls(&sym->st_value); | |
463 | + bswaptls(&sym->st_size); | |
439 | 464 | bswap16s(&sym->st_shndx); |
440 | 465 | } |
441 | 466 | #endif | ... | ... |
linux-user/main.c
... | ... | @@ -1534,6 +1534,96 @@ void cpu_loop(CPUM68KState *env) |
1534 | 1534 | } |
1535 | 1535 | #endif /* TARGET_M68K */ |
1536 | 1536 | |
1537 | +#ifdef TARGET_ALPHA | |
1538 | +void cpu_loop (CPUState *env) | |
1539 | +{ | |
1540 | + int trapnr, ret; | |
1541 | + target_siginfo_t info; | |
1542 | + | |
1543 | + while (1) { | |
1544 | + trapnr = cpu_alpha_exec (env); | |
1545 | + | |
1546 | + switch (trapnr) { | |
1547 | + case EXCP_RESET: | |
1548 | + fprintf(stderr, "Reset requested. Exit\n"); | |
1549 | + exit(1); | |
1550 | + break; | |
1551 | + case EXCP_MCHK: | |
1552 | + fprintf(stderr, "Machine check exception. Exit\n"); | |
1553 | + exit(1); | |
1554 | + break; | |
1555 | + case EXCP_ARITH: | |
1556 | + fprintf(stderr, "Arithmetic trap.\n"); | |
1557 | + exit(1); | |
1558 | + break; | |
1559 | + case EXCP_HW_INTERRUPT: | |
1560 | + fprintf(stderr, "External interrupt. Exit\n"); | |
1561 | + exit(1); | |
1562 | + break; | |
1563 | + case EXCP_DFAULT: | |
1564 | + fprintf(stderr, "MMU data fault\n"); | |
1565 | + exit(1); | |
1566 | + break; | |
1567 | + case EXCP_DTB_MISS_PAL: | |
1568 | + fprintf(stderr, "MMU data TLB miss in PALcode\n"); | |
1569 | + exit(1); | |
1570 | + break; | |
1571 | + case EXCP_ITB_MISS: | |
1572 | + fprintf(stderr, "MMU instruction TLB miss\n"); | |
1573 | + exit(1); | |
1574 | + break; | |
1575 | + case EXCP_ITB_ACV: | |
1576 | + fprintf(stderr, "MMU instruction access violation\n"); | |
1577 | + exit(1); | |
1578 | + break; | |
1579 | + case EXCP_DTB_MISS_NATIVE: | |
1580 | + fprintf(stderr, "MMU data TLB miss\n"); | |
1581 | + exit(1); | |
1582 | + break; | |
1583 | + case EXCP_UNALIGN: | |
1584 | + fprintf(stderr, "Unaligned access\n"); | |
1585 | + exit(1); | |
1586 | + break; | |
1587 | + case EXCP_OPCDEC: | |
1588 | + fprintf(stderr, "Invalid instruction\n"); | |
1589 | + exit(1); | |
1590 | + break; | |
1591 | + case EXCP_FEN: | |
1592 | + fprintf(stderr, "Floating-point not allowed\n"); | |
1593 | + exit(1); | |
1594 | + break; | |
1595 | + case EXCP_CALL_PAL ... (EXCP_CALL_PALP - 1): | |
1596 | + fprintf(stderr, "Call to PALcode\n"); | |
1597 | + call_pal(env, (trapnr >> 6) | 0x80); | |
1598 | + break; | |
1599 | + case EXCP_CALL_PALP ... (EXCP_CALL_PALE - 1): | |
1600 | + fprintf(stderr, "Priviledged call to PALcode\n"); | |
1601 | + exit(1); | |
1602 | + break; | |
1603 | + case EXCP_DEBUG: | |
1604 | + { | |
1605 | + int sig; | |
1606 | + | |
1607 | + sig = gdb_handlesig (env, TARGET_SIGTRAP); | |
1608 | + if (sig) | |
1609 | + { | |
1610 | + info.si_signo = sig; | |
1611 | + info.si_errno = 0; | |
1612 | + info.si_code = TARGET_TRAP_BRKPT; | |
1613 | + queue_signal(info.si_signo, &info); | |
1614 | + } | |
1615 | + } | |
1616 | + break; | |
1617 | + default: | |
1618 | + printf ("Unhandled trap: 0x%x\n", trapnr); | |
1619 | + cpu_dump_state(env, stderr, fprintf, 0); | |
1620 | + exit (1); | |
1621 | + } | |
1622 | + process_pending_signals (env); | |
1623 | + } | |
1624 | +} | |
1625 | +#endif /* TARGET_ALPHA */ | |
1626 | + | |
1537 | 1627 | void usage(void) |
1538 | 1628 | { |
1539 | 1629 | printf("qemu-" TARGET_ARCH " version " QEMU_VERSION ", Copyright (c) 2003-2007 Fabrice Bellard\n" |
... | ... | @@ -1877,6 +1967,18 @@ int main(int argc, char **argv) |
1877 | 1967 | } |
1878 | 1968 | env->pc = regs->pc; |
1879 | 1969 | } |
1970 | +#elif defined(TARGET_ALPHA) | |
1971 | + { | |
1972 | + int i; | |
1973 | + | |
1974 | + for(i = 0; i < 28; i++) { | |
1975 | + env->ir[i] = ((target_ulong *)regs)[i]; | |
1976 | + } | |
1977 | + env->ipr[IPR_USP] = regs->usp; | |
1978 | + env->ir[30] = regs->usp; | |
1979 | + env->pc = regs->pc; | |
1980 | + env->unique = regs->unique; | |
1981 | + } | |
1880 | 1982 | #else |
1881 | 1983 | #error unsupported target CPU |
1882 | 1984 | #endif | ... | ... |
linux-user/syscall.c
... | ... | @@ -1765,6 +1765,16 @@ int do_fork(CPUState *env, unsigned int flags, unsigned long newsp) |
1765 | 1765 | newsp = env->gregs[15]; |
1766 | 1766 | new_env->gregs[15] = newsp; |
1767 | 1767 | /* XXXXX */ |
1768 | +#elif defined(TARGET_ALPHA) | |
1769 | + if (!newsp) | |
1770 | + newsp = env->ir[30]; | |
1771 | + new_env->ir[30] = newsp; | |
1772 | + /* ? */ | |
1773 | + { | |
1774 | + int i; | |
1775 | + for (i = 7; i < 30; i++) | |
1776 | + new_env->ir[i] = 0; | |
1777 | + } | |
1768 | 1778 | #else |
1769 | 1779 | #error unsupported target CPU |
1770 | 1780 | #endif |
... | ... | @@ -2067,11 +2077,13 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, |
2067 | 2077 | } |
2068 | 2078 | break; |
2069 | 2079 | #endif |
2080 | +#ifdef TARGET_NR_creat /* not on alpha */ | |
2070 | 2081 | case TARGET_NR_creat: |
2071 | 2082 | p = lock_user_string(arg1); |
2072 | 2083 | ret = get_errno(creat(p, arg2)); |
2073 | 2084 | unlock_user(p, arg1, 0); |
2074 | 2085 | break; |
2086 | +#endif | |
2075 | 2087 | case TARGET_NR_link: |
2076 | 2088 | { |
2077 | 2089 | void * p2; |
... | ... | @@ -2179,7 +2191,11 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, |
2179 | 2191 | case TARGET_NR_lseek: |
2180 | 2192 | ret = get_errno(lseek(arg1, arg2, arg3)); |
2181 | 2193 | break; |
2194 | +#ifdef TARGET_NR_getxpid | |
2195 | + case TARGET_NR_getxpid: | |
2196 | +#else | |
2182 | 2197 | case TARGET_NR_getpid: |
2198 | +#endif | |
2183 | 2199 | ret = get_errno(getpid()); |
2184 | 2200 | break; |
2185 | 2201 | case TARGET_NR_mount: |
... | ... | @@ -2202,6 +2218,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, |
2202 | 2218 | unlock_user(p, arg1, 0); |
2203 | 2219 | break; |
2204 | 2220 | #endif |
2221 | +#ifdef TARGET_NR_stime /* not on alpha */ | |
2205 | 2222 | case TARGET_NR_stime: |
2206 | 2223 | { |
2207 | 2224 | time_t host_time; |
... | ... | @@ -2209,18 +2226,23 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, |
2209 | 2226 | ret = get_errno(stime(&host_time)); |
2210 | 2227 | } |
2211 | 2228 | break; |
2229 | +#endif | |
2212 | 2230 | case TARGET_NR_ptrace: |
2213 | 2231 | goto unimplemented; |
2232 | +#ifdef TARGET_NR_alarm /* not on alpha */ | |
2214 | 2233 | case TARGET_NR_alarm: |
2215 | 2234 | ret = alarm(arg1); |
2216 | 2235 | break; |
2236 | +#endif | |
2217 | 2237 | #ifdef TARGET_NR_oldfstat |
2218 | 2238 | case TARGET_NR_oldfstat: |
2219 | 2239 | goto unimplemented; |
2220 | 2240 | #endif |
2241 | +#ifdef TARGET_NR_pause /* not on alpha */ | |
2221 | 2242 | case TARGET_NR_pause: |
2222 | 2243 | ret = get_errno(pause()); |
2223 | 2244 | break; |
2245 | +#endif | |
2224 | 2246 | #ifdef TARGET_NR_utime |
2225 | 2247 | case TARGET_NR_utime: |
2226 | 2248 | { |
... | ... | @@ -2270,9 +2292,11 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, |
2270 | 2292 | ret = get_errno(access(p, arg2)); |
2271 | 2293 | unlock_user(p, arg1, 0); |
2272 | 2294 | break; |
2295 | +#ifdef TARGET_NR_nice /* not on alpha */ | |
2273 | 2296 | case TARGET_NR_nice: |
2274 | 2297 | ret = get_errno(nice(arg1)); |
2275 | 2298 | break; |
2299 | +#endif | |
2276 | 2300 | #ifdef TARGET_NR_ftime |
2277 | 2301 | case TARGET_NR_ftime: |
2278 | 2302 | goto unimplemented; |
... | ... | @@ -2346,11 +2370,13 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, |
2346 | 2370 | ret = get_errno(acct(path(p))); |
2347 | 2371 | unlock_user(p, arg1, 0); |
2348 | 2372 | break; |
2373 | +#ifdef TARGET_NR_umount2 /* not on alpha */ | |
2349 | 2374 | case TARGET_NR_umount2: |
2350 | 2375 | p = lock_user_string(arg1); |
2351 | 2376 | ret = get_errno(umount2(p, arg2)); |
2352 | 2377 | unlock_user(p, arg1, 0); |
2353 | 2378 | break; |
2379 | +#endif | |
2354 | 2380 | #ifdef TARGET_NR_lock |
2355 | 2381 | case TARGET_NR_lock: |
2356 | 2382 | goto unimplemented; |
... | ... | @@ -2389,9 +2415,11 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, |
2389 | 2415 | case TARGET_NR_dup2: |
2390 | 2416 | ret = get_errno(dup2(arg1, arg2)); |
2391 | 2417 | break; |
2418 | +#ifdef TARGET_NR_getppid /* not on alpha */ | |
2392 | 2419 | case TARGET_NR_getppid: |
2393 | 2420 | ret = get_errno(getppid()); |
2394 | 2421 | break; |
2422 | +#endif | |
2395 | 2423 | case TARGET_NR_getpgrp: |
2396 | 2424 | ret = get_errno(getpgrp()); |
2397 | 2425 | break; |
... | ... | @@ -2474,6 +2502,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, |
2474 | 2502 | unlock_user_struct(oact, arg3, 1); |
2475 | 2503 | } |
2476 | 2504 | break; |
2505 | +#ifdef TARGET_NR_sgetmask /* not on alpha */ | |
2477 | 2506 | case TARGET_NR_sgetmask: |
2478 | 2507 | { |
2479 | 2508 | sigset_t cur_set; |
... | ... | @@ -2483,6 +2512,8 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, |
2483 | 2512 | ret = target_set; |
2484 | 2513 | } |
2485 | 2514 | break; |
2515 | +#endif | |
2516 | +#ifdef TARGET_NR_ssetmask /* not on alpha */ | |
2486 | 2517 | case TARGET_NR_ssetmask: |
2487 | 2518 | { |
2488 | 2519 | sigset_t set, oset, cur_set; |
... | ... | @@ -2495,6 +2526,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, |
2495 | 2526 | ret = target_set; |
2496 | 2527 | } |
2497 | 2528 | break; |
2529 | +#endif | |
2498 | 2530 | #ifdef TARGET_NR_sigprocmask |
2499 | 2531 | case TARGET_NR_sigprocmask: |
2500 | 2532 | { |
... | ... | @@ -3256,6 +3288,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, |
3256 | 3288 | case TARGET_NR_afs_syscall: |
3257 | 3289 | goto unimplemented; |
3258 | 3290 | #endif |
3291 | +#ifdef TARGET_NR__llseek /* Not on alpha */ | |
3259 | 3292 | case TARGET_NR__llseek: |
3260 | 3293 | { |
3261 | 3294 | #if defined (__x86_64__) |
... | ... | @@ -3268,6 +3301,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, |
3268 | 3301 | #endif |
3269 | 3302 | } |
3270 | 3303 | break; |
3304 | +#endif | |
3271 | 3305 | case TARGET_NR_getdents: |
3272 | 3306 | #if TARGET_LONG_SIZE != 4 |
3273 | 3307 | goto unimplemented; |
... | ... | @@ -3431,9 +3465,11 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, |
3431 | 3465 | case TARGET_NR_getsid: |
3432 | 3466 | ret = get_errno(getsid(arg1)); |
3433 | 3467 | break; |
3468 | +#if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */ | |
3434 | 3469 | case TARGET_NR_fdatasync: |
3435 | 3470 | ret = get_errno(fdatasync(arg1)); |
3436 | 3471 | break; |
3472 | +#endif | |
3437 | 3473 | case TARGET_NR__sysctl: |
3438 | 3474 | /* We don't implement this, but ENODIR is always a safe |
3439 | 3475 | return value. */ | ... | ... |
linux-user/syscall_defs.h
... | ... | @@ -49,7 +49,7 @@ |
49 | 49 | #define TARGET_IOC_TYPEBITS 8 |
50 | 50 | |
51 | 51 | #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SH4) \ |
52 | - || defined(TARGET_M68K) | |
52 | + || defined(TARGET_M68K) || defined(TARGET_ALPHA) | |
53 | 53 | |
54 | 54 | #define TARGET_IOC_SIZEBITS 14 |
55 | 55 | #define TARGET_IOC_DIRBITS 2 |
... | ... | @@ -294,7 +294,7 @@ struct target_sigaction; |
294 | 294 | int do_sigaction(int sig, const struct target_sigaction *act, |
295 | 295 | struct target_sigaction *oact); |
296 | 296 | |
297 | -#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_MIPS) || defined (TARGET_SH4) || defined(TARGET_M68K) | |
297 | +#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_MIPS) || defined (TARGET_SH4) || defined(TARGET_M68K) || defined(TARGET_ALPHA) | |
298 | 298 | |
299 | 299 | #if defined(TARGET_SPARC) |
300 | 300 | #define TARGET_SA_NOCLDSTOP 8u |
... | ... | @@ -1203,6 +1203,50 @@ struct target_stat64 { |
1203 | 1203 | |
1204 | 1204 | int64_t st_blocks; |
1205 | 1205 | }; |
1206 | + | |
1207 | +#elif defined(TARGET_ALPHA) | |
1208 | + | |
1209 | +struct target_stat { | |
1210 | + unsigned int st_dev; | |
1211 | + unsigned int st_ino; | |
1212 | + unsigned int st_mode; | |
1213 | + unsigned int st_nlink; | |
1214 | + unsigned int st_uid; | |
1215 | + unsigned int st_gid; | |
1216 | + unsigned int st_rdev; | |
1217 | + target_long st_size; | |
1218 | + target_ulong target_st_atime; | |
1219 | + target_ulong target_st_mtime; | |
1220 | + target_ulong target_st_ctime; | |
1221 | + unsigned int st_blksize; | |
1222 | + unsigned int st_blocks; | |
1223 | + unsigned int st_flags; | |
1224 | + unsigned int st_gen; | |
1225 | +}; | |
1226 | + | |
1227 | +struct target_stat64 { | |
1228 | + target_ulong st_dev; | |
1229 | + target_ulong st_ino; | |
1230 | + target_ulong st_rdev; | |
1231 | + target_long st_size; | |
1232 | + target_ulong st_blocks; | |
1233 | + | |
1234 | + unsigned int st_mode; | |
1235 | + unsigned int st_uid; | |
1236 | + unsigned int st_gid; | |
1237 | + unsigned int st_blksize; | |
1238 | + unsigned int st_nlink; | |
1239 | + unsigned int __pad0; | |
1240 | + | |
1241 | + target_ulong target_st_atime; | |
1242 | + target_ulong target_st_atime_nsec; | |
1243 | + target_ulong target_st_mtime; | |
1244 | + target_ulong target_st_mtime_nsec; | |
1245 | + target_ulong target_st_ctime; | |
1246 | + target_ulong target_st_ctime_nsec; | |
1247 | + target_long __unused[3]; | |
1248 | +}; | |
1249 | + | |
1206 | 1250 | #else |
1207 | 1251 | #error unsupported CPU |
1208 | 1252 | #endif | ... | ... |