Commit edf8e2af1453ce56c72b2f25a745e3734177a05d

Authored by Mika Westerberg
Committed by Riku Voipio
1 parent 88a8c984

linux-user: implemented ELF coredump support for ARM target

When target process is killed with signal (such signal that
should dump core) a coredump file is created.  This file is
similar than coredump generated by Linux (there are few exceptions
though).

Riku Voipio: added support for rlimit

Signed-off-by: Mika Westerberg <mika.westerberg@iki.fi>
Signed-off-by: Riku Voipio <riku.voipio@iki.fi>
cpu-all.h
... ... @@ -735,6 +735,8 @@ extern unsigned long qemu_host_page_mask;
735 735 #define PAGE_RESERVED 0x0020
736 736  
737 737 void page_dump(FILE *f);
  738 +int walk_memory_regions(void *,
  739 + int (*fn)(void *, unsigned long, unsigned long, unsigned long));
738 740 int page_get_flags(target_ulong address);
739 741 void page_set_flags(target_ulong start, target_ulong end, int flags);
740 742 int page_check_range(target_ulong start, target_ulong len, int flags);
... ...
... ... @@ -1081,7 +1081,23 @@ typedef struct elf64_shdr {
1081 1081 #define EI_CLASS 4
1082 1082 #define EI_DATA 5
1083 1083 #define EI_VERSION 6
1084   -#define EI_PAD 7
  1084 +#define EI_OSABI 7
  1085 +#define EI_PAD 8
  1086 +
  1087 +#define ELFOSABI_NONE 0 /* UNIX System V ABI */
  1088 +#define ELFOSABI_SYSV 0 /* Alias. */
  1089 +#define ELFOSABI_HPUX 1 /* HP-UX */
  1090 +#define ELFOSABI_NETBSD 2 /* NetBSD. */
  1091 +#define ELFOSABI_LINUX 3 /* Linux. */
  1092 +#define ELFOSABI_SOLARIS 6 /* Sun Solaris. */
  1093 +#define ELFOSABI_AIX 7 /* IBM AIX. */
  1094 +#define ELFOSABI_IRIX 8 /* SGI Irix. */
  1095 +#define ELFOSABI_FREEBSD 9 /* FreeBSD. */
  1096 +#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX. */
  1097 +#define ELFOSABI_MODESTO 11 /* Novell Modesto. */
  1098 +#define ELFOSABI_OPENBSD 12 /* OpenBSD. */
  1099 +#define ELFOSABI_ARM 97 /* ARM */
  1100 +#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */
1085 1101  
1086 1102 #define ELFMAG0 0x7f /* EI_MAG */
1087 1103 #define ELFMAG1 'E'
... ... @@ -1108,6 +1124,7 @@ typedef struct elf64_shdr {
1108 1124 #define NT_PRFPREG 2
1109 1125 #define NT_PRPSINFO 3
1110 1126 #define NT_TASKSTRUCT 4
  1127 +#define NT_AUXV 6
1111 1128 #define NT_PRXFPREG 0x46e62b7f /* copied from gdb5.1/include/elf/common.h */
1112 1129  
1113 1130  
... ...
... ... @@ -2131,36 +2131,36 @@ int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
2131 2131 return 0;
2132 2132 }
2133 2133  
2134   -/* dump memory mappings */
2135   -void page_dump(FILE *f)
  2134 +/*
  2135 + * Walks guest process memory "regions" one by one
  2136 + * and calls callback function 'fn' for each region.
  2137 + */
  2138 +int walk_memory_regions(void *priv,
  2139 + int (*fn)(void *, unsigned long, unsigned long, unsigned long))
2136 2140 {
2137 2141 unsigned long start, end;
  2142 + PageDesc *p = NULL;
2138 2143 int i, j, prot, prot1;
2139   - PageDesc *p;
  2144 + int rc = 0;
2140 2145  
2141   - fprintf(f, "%-8s %-8s %-8s %s\n",
2142   - "start", "end", "size", "prot");
2143   - start = -1;
2144   - end = -1;
  2146 + start = end = -1;
2145 2147 prot = 0;
2146   - for(i = 0; i <= L1_SIZE; i++) {
2147   - if (i < L1_SIZE)
2148   - p = l1_map[i];
2149   - else
2150   - p = NULL;
2151   - for(j = 0;j < L2_SIZE; j++) {
2152   - if (!p)
2153   - prot1 = 0;
2154   - else
2155   - prot1 = p[j].flags;
  2148 +
  2149 + for (i = 0; i <= L1_SIZE; i++) {
  2150 + p = (i < L1_SIZE) ? l1_map[i] : NULL;
  2151 + for (j = 0; j < L2_SIZE; j++) {
  2152 + prot1 = (p == NULL) ? 0 : p[j].flags;
  2153 + /*
  2154 + * "region" is one continuous chunk of memory
  2155 + * that has same protection flags set.
  2156 + */
2156 2157 if (prot1 != prot) {
2157 2158 end = (i << (32 - L1_BITS)) | (j << TARGET_PAGE_BITS);
2158 2159 if (start != -1) {
2159   - fprintf(f, "%08lx-%08lx %08lx %c%c%c\n",
2160   - start, end, end - start,
2161   - prot & PAGE_READ ? 'r' : '-',
2162   - prot & PAGE_WRITE ? 'w' : '-',
2163   - prot & PAGE_EXEC ? 'x' : '-');
  2160 + rc = (*fn)(priv, start, end, prot);
  2161 + /* callback can stop iteration by returning != 0 */
  2162 + if (rc != 0)
  2163 + return (rc);
2164 2164 }
2165 2165 if (prot1 != 0)
2166 2166 start = end;
... ... @@ -2168,10 +2168,33 @@ void page_dump(FILE *f)
2168 2168 start = -1;
2169 2169 prot = prot1;
2170 2170 }
2171   - if (!p)
  2171 + if (p == NULL)
2172 2172 break;
2173 2173 }
2174 2174 }
  2175 + return (rc);
  2176 +}
  2177 +
  2178 +static int dump_region(void *priv, unsigned long start,
  2179 + unsigned long end, unsigned long prot)
  2180 +{
  2181 + FILE *f = (FILE *)priv;
  2182 +
  2183 + (void) fprintf(f, "%08lx-%08lx %08lx %c%c%c\n",
  2184 + start, end, end - start,
  2185 + ((prot & PAGE_READ) ? 'r' : '-'),
  2186 + ((prot & PAGE_WRITE) ? 'w' : '-'),
  2187 + ((prot & PAGE_EXEC) ? 'x' : '-'));
  2188 +
  2189 + return (0);
  2190 +}
  2191 +
  2192 +/* dump memory mappings */
  2193 +void page_dump(FILE *f)
  2194 +{
  2195 + (void) fprintf(f, "%-8s %-8s %-8s %s\n",
  2196 + "start", "end", "size", "prot");
  2197 + walk_memory_regions(f, dump_region);
2175 2198 }
2176 2199  
2177 2200 int page_get_flags(target_ulong address)
... ...
linux-user/elfload.c
1 1 /* This is the Linux kernel elf-loading code, ported into user space */
  2 +#include <sys/time.h>
  3 +#include <sys/param.h>
2 4  
3 5 #include <stdio.h>
4 6 #include <sys/types.h>
... ... @@ -6,8 +8,10 @@
6 8 #include <errno.h>
7 9 #include <unistd.h>
8 10 #include <sys/mman.h>
  11 +#include <sys/resource.h>
9 12 #include <stdlib.h>
10 13 #include <string.h>
  14 +#include <time.h>
11 15  
12 16 #include "qemu.h"
13 17 #include "disas.h"
... ... @@ -21,6 +25,8 @@
21 25 #undef ELF_ARCH
22 26 #endif
23 27  
  28 +#define ELF_OSABI ELFOSABI_SYSV
  29 +
24 30 /* from personality.h */
25 31  
26 32 /*
... ... @@ -160,7 +166,6 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i
160 166 }
161 167 #endif
162 168  
163   -#define USE_ELF_CORE_DUMP
164 169 #define ELF_EXEC_PAGESIZE 4096
165 170  
166 171 #endif
... ... @@ -198,6 +203,37 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i
198 203 regs->ARM_r10 = infop->start_data;
199 204 }
200 205  
  206 +typedef uint32_t elf_greg_t;
  207 +typedef uint16_t target_uid_t;
  208 +typedef uint16_t target_gid_t;
  209 +typedef int32_t target_pid_t;
  210 +
  211 +#define ELF_NREG 18
  212 +typedef elf_greg_t elf_gregset_t[ELF_NREG];
  213 +
  214 +static void elf_core_copy_regs(elf_gregset_t *regs, const CPUState *env)
  215 +{
  216 + (*regs)[0] = env->regs[0];
  217 + (*regs)[1] = env->regs[1];
  218 + (*regs)[2] = env->regs[2];
  219 + (*regs)[3] = env->regs[3];
  220 + (*regs)[4] = env->regs[4];
  221 + (*regs)[5] = env->regs[5];
  222 + (*regs)[6] = env->regs[6];
  223 + (*regs)[7] = env->regs[7];
  224 + (*regs)[8] = env->regs[8];
  225 + (*regs)[9] = env->regs[9];
  226 + (*regs)[10] = env->regs[10];
  227 + (*regs)[11] = env->regs[11];
  228 + (*regs)[12] = env->regs[12];
  229 + (*regs)[13] = env->regs[13];
  230 + (*regs)[14] = env->regs[14];
  231 + (*regs)[15] = env->regs[15];
  232 +
  233 + (*regs)[16] = cpsr_read((CPUState *)env);
  234 + (*regs)[17] = env->regs[0]; /* XXX */
  235 +}
  236 +
201 237 #define USE_ELF_CORE_DUMP
202 238 #define ELF_EXEC_PAGESIZE 4096
203 239  
... ... @@ -418,7 +454,6 @@ static inline void init_thread(struct target_pt_regs *_regs, struct image_info *
418 454 _regs->gpr[5] = pos;
419 455 }
420 456  
421   -#define USE_ELF_CORE_DUMP
422 457 #define ELF_EXEC_PAGESIZE 4096
423 458  
424 459 #endif
... ... @@ -448,7 +483,6 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i
448 483 regs->regs[29] = infop->start_stack;
449 484 }
450 485  
451   -#define USE_ELF_CORE_DUMP
452 486 #define ELF_EXEC_PAGESIZE 4096
453 487  
454 488 #endif /* TARGET_MIPS */
... ... @@ -470,7 +504,6 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i
470 504  
471 505 }
472 506  
473   -#define USE_ELF_CORE_DUMP
474 507 #define ELF_EXEC_PAGESIZE 4096
475 508  
476 509 #endif /* TARGET_MICROBLAZE */
... ... @@ -492,7 +525,6 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i
492 525 regs->regs[15] = infop->start_stack;
493 526 }
494 527  
495   -#define USE_ELF_CORE_DUMP
496 528 #define ELF_EXEC_PAGESIZE 4096
497 529  
498 530 #endif
... ... @@ -512,7 +544,6 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i
512 544 regs->erp = infop->entry;
513 545 }
514 546  
515   -#define USE_ELF_CORE_DUMP
516 547 #define ELF_EXEC_PAGESIZE 8192
517 548  
518 549 #endif
... ... @@ -537,7 +568,6 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i
537 568 regs->pc = infop->entry;
538 569 }
539 570  
540   -#define USE_ELF_CORE_DUMP
541 571 #define ELF_EXEC_PAGESIZE 8192
542 572  
543 573 #endif
... ... @@ -562,7 +592,6 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i
562 592 regs->unique, infop->start_data);
563 593 }
564 594  
565   -#define USE_ELF_CORE_DUMP
566 595 #define ELF_EXEC_PAGESIZE 8192
567 596  
568 597 #endif /* TARGET_ALPHA */
... ... @@ -680,6 +709,20 @@ static void bswap_sym(struct elf_sym *sym)
680 709 }
681 710 #endif
682 711  
  712 +#ifdef USE_ELF_CORE_DUMP
  713 +static int elf_core_dump(int, const CPUState *);
  714 +
  715 +#ifdef BSWAP_NEEDED
  716 +static void bswap_note(struct elf_note *en)
  717 +{
  718 + bswaptls(&en->n_namesz);
  719 + bswaptls(&en->n_descsz);
  720 + bswaptls(&en->n_type);
  721 +}
  722 +#endif /* BSWAP_NEEDED */
  723 +
  724 +#endif /* USE_ELF_CORE_DUMP */
  725 +
683 726 /*
684 727 * 'copy_elf_strings()' copies argument/envelope strings from user
685 728 * memory to free pages in kernel mem. These are in a format ready
... ... @@ -904,6 +947,8 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
904 947 #endif
905 948 #undef NEW_AUX_ENT
906 949  
  950 + info->saved_auxv = sp;
  951 +
907 952 sp = loader_build_argptr(envc, argc, sp, p, !ibcs);
908 953 return sp;
909 954 }
... ... @@ -1586,9 +1631,876 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
1586 1631  
1587 1632 info->entry = elf_entry;
1588 1633  
  1634 +#ifdef USE_ELF_CORE_DUMP
  1635 + bprm->core_dump = &elf_core_dump;
  1636 +#endif
  1637 +
1589 1638 return 0;
1590 1639 }
1591 1640  
  1641 +#ifdef USE_ELF_CORE_DUMP
  1642 +
  1643 +/*
  1644 + * Definitions to generate Intel SVR4-like core files.
  1645 + * These mostly have the same names as the SVR4 types with "elf_"
  1646 + * tacked on the front to prevent clashes with linux definitions,
  1647 + * and the typedef forms have been avoided. This is mostly like
  1648 + * the SVR4 structure, but more Linuxy, with things that Linux does
  1649 + * not support and which gdb doesn't really use excluded.
  1650 + *
  1651 + * Fields we don't dump (their contents is zero) in linux-user qemu
  1652 + * are marked with XXX.
  1653 + *
  1654 + * Core dump code is copied from linux kernel (fs/binfmt_elf.c).
  1655 + *
  1656 + * Porting ELF coredump for target is (quite) simple process. First you
  1657 + * define ELF_USE_CORE_DUMP in target ELF code (where init_thread() for
  1658 + * the target resides):
  1659 + *
  1660 + * #define USE_ELF_CORE_DUMP
  1661 + *
  1662 + * Next you define type of register set used for dumping. ELF specification
  1663 + * says that it needs to be array of elf_greg_t that has size of ELF_NREG.
  1664 + *
  1665 + * typedef <target_regtype> elf_greg_t;
  1666 + * #define ELF_NREG <number of registers>
  1667 + * typedef elf_greg_t elf_gregset_t[ELF_NREG];
  1668 + *
  1669 + * Then define following types to match target types. Actual types can
  1670 + * be found from linux kernel (arch/<ARCH>/include/asm/posix_types.h):
  1671 + *
  1672 + * typedef <target_uid_type> target_uid_t;
  1673 + * typedef <target_gid_type> target_gid_t;
  1674 + * typedef <target_pid_type> target_pid_t;
  1675 + *
  1676 + * Last step is to implement target specific function that copies registers
  1677 + * from given cpu into just specified register set. Prototype is:
  1678 + *
  1679 + * static void elf_core_copy_regs(elf_gregset_t *regs, const CPUState *env);
  1680 + *
  1681 + * Parameters:
  1682 + * regs - copy register values into here (allocated and zeroed by caller)
  1683 + * env - copy registers from here
  1684 + *
  1685 + * Example for ARM target is provided in this file.
  1686 + */
  1687 +
  1688 +/* An ELF note in memory */
  1689 +struct memelfnote {
  1690 + const char *name;
  1691 + size_t namesz;
  1692 + size_t namesz_rounded;
  1693 + int type;
  1694 + size_t datasz;
  1695 + void *data;
  1696 + size_t notesz;
  1697 +};
  1698 +
  1699 +struct elf_siginfo {
  1700 + int si_signo; /* signal number */
  1701 + int si_code; /* extra code */
  1702 + int si_errno; /* errno */
  1703 +};
  1704 +
  1705 +struct elf_prstatus {
  1706 + struct elf_siginfo pr_info; /* Info associated with signal */
  1707 + short pr_cursig; /* Current signal */
  1708 + target_ulong pr_sigpend; /* XXX */
  1709 + target_ulong pr_sighold; /* XXX */
  1710 + target_pid_t pr_pid;
  1711 + target_pid_t pr_ppid;
  1712 + target_pid_t pr_pgrp;
  1713 + target_pid_t pr_sid;
  1714 + struct target_timeval pr_utime; /* XXX User time */
  1715 + struct target_timeval pr_stime; /* XXX System time */
  1716 + struct target_timeval pr_cutime; /* XXX Cumulative user time */
  1717 + struct target_timeval pr_cstime; /* XXX Cumulative system time */
  1718 + elf_gregset_t pr_reg; /* GP registers */
  1719 + int pr_fpvalid; /* XXX */
  1720 +};
  1721 +
  1722 +#define ELF_PRARGSZ (80) /* Number of chars for args */
  1723 +
  1724 +struct elf_prpsinfo {
  1725 + char pr_state; /* numeric process state */
  1726 + char pr_sname; /* char for pr_state */
  1727 + char pr_zomb; /* zombie */
  1728 + char pr_nice; /* nice val */
  1729 + target_ulong pr_flag; /* flags */
  1730 + target_uid_t pr_uid;
  1731 + target_gid_t pr_gid;
  1732 + target_pid_t pr_pid, pr_ppid, pr_pgrp, pr_sid;
  1733 + /* Lots missing */
  1734 + char pr_fname[16]; /* filename of executable */
  1735 + char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */
  1736 +};
  1737 +
  1738 +/* Here is the structure in which status of each thread is captured. */
  1739 +struct elf_thread_status {
  1740 + TAILQ_ENTRY(elf_thread_status) ets_link;
  1741 + struct elf_prstatus prstatus; /* NT_PRSTATUS */
  1742 +#if 0
  1743 + elf_fpregset_t fpu; /* NT_PRFPREG */
  1744 + struct task_struct *thread;
  1745 + elf_fpxregset_t xfpu; /* ELF_CORE_XFPREG_TYPE */
  1746 +#endif
  1747 + struct memelfnote notes[1];
  1748 + int num_notes;
  1749 +};
  1750 +
  1751 +struct elf_note_info {
  1752 + struct memelfnote *notes;
  1753 + struct elf_prstatus *prstatus; /* NT_PRSTATUS */
  1754 + struct elf_prpsinfo *psinfo; /* NT_PRPSINFO */
  1755 +
  1756 + TAILQ_HEAD(thread_list_head, elf_thread_status) thread_list;
  1757 +#if 0
  1758 + /*
  1759 + * Current version of ELF coredump doesn't support
  1760 + * dumping fp regs etc.
  1761 + */
  1762 + elf_fpregset_t *fpu;
  1763 + elf_fpxregset_t *xfpu;
  1764 + int thread_status_size;
  1765 +#endif
  1766 + int notes_size;
  1767 + int numnote;
  1768 +};
  1769 +
  1770 +struct vm_area_struct {
  1771 + abi_ulong vma_start; /* start vaddr of memory region */
  1772 + abi_ulong vma_end; /* end vaddr of memory region */
  1773 + abi_ulong vma_flags; /* protection etc. flags for the region */
  1774 + TAILQ_ENTRY(vm_area_struct) vma_link;
  1775 +};
  1776 +
  1777 +struct mm_struct {
  1778 + TAILQ_HEAD(, vm_area_struct) mm_mmap;
  1779 + int mm_count; /* number of mappings */
  1780 +};
  1781 +
  1782 +static struct mm_struct *vma_init(void);
  1783 +static void vma_delete(struct mm_struct *);
  1784 +static int vma_add_mapping(struct mm_struct *, abi_ulong,
  1785 + abi_ulong, abi_ulong);
  1786 +static int vma_get_mapping_count(const struct mm_struct *);
  1787 +static struct vm_area_struct *vma_first(const struct mm_struct *);
  1788 +static struct vm_area_struct *vma_next(struct vm_area_struct *);
  1789 +static abi_ulong vma_dump_size(const struct vm_area_struct *);
  1790 +static int vma_walker(void *priv, unsigned long start, unsigned long end,
  1791 + unsigned long flags);
  1792 +
  1793 +static void fill_elf_header(struct elfhdr *, int, uint16_t, uint32_t);
  1794 +static void fill_note(struct memelfnote *, const char *, int,
  1795 + unsigned int, void *);
  1796 +static void fill_prstatus(struct elf_prstatus *, const TaskState *, int);
  1797 +static int fill_psinfo(struct elf_prpsinfo *, const TaskState *);
  1798 +static void fill_auxv_note(struct memelfnote *, const TaskState *);
  1799 +static void fill_elf_note_phdr(struct elf_phdr *, int, off_t);
  1800 +static size_t note_size(const struct memelfnote *);
  1801 +static void free_note_info(struct elf_note_info *);
  1802 +static int fill_note_info(struct elf_note_info *, long, const CPUState *);
  1803 +static void fill_thread_info(struct elf_note_info *, const CPUState *);
  1804 +static int core_dump_filename(const TaskState *, char *, size_t);
  1805 +
  1806 +static int dump_write(int, const void *, size_t);
  1807 +static int write_note(struct memelfnote *, int);
  1808 +static int write_note_info(struct elf_note_info *, int);
  1809 +
  1810 +#ifdef BSWAP_NEEDED
  1811 +static void bswap_prstatus(struct elf_prstatus *);
  1812 +static void bswap_psinfo(struct elf_prpsinfo *);
  1813 +
  1814 +static void bswap_prstatus(struct elf_prstatus *prstatus)
  1815 +{
  1816 + prstatus->pr_info.si_signo = tswapl(prstatus->pr_info.si_signo);
  1817 + prstatus->pr_info.si_code = tswapl(prstatus->pr_info.si_code);
  1818 + prstatus->pr_info.si_errno = tswapl(prstatus->pr_info.si_errno);
  1819 + prstatus->pr_cursig = tswap16(prstatus->pr_cursig);
  1820 + prstatus->pr_sigpend = tswapl(prstatus->pr_sigpend);
  1821 + prstatus->pr_sighold = tswapl(prstatus->pr_sighold);
  1822 + prstatus->pr_pid = tswap32(prstatus->pr_pid);
  1823 + prstatus->pr_ppid = tswap32(prstatus->pr_ppid);
  1824 + prstatus->pr_pgrp = tswap32(prstatus->pr_pgrp);
  1825 + prstatus->pr_sid = tswap32(prstatus->pr_sid);
  1826 + /* cpu times are not filled, so we skip them */
  1827 + /* regs should be in correct format already */
  1828 + prstatus->pr_fpvalid = tswap32(prstatus->pr_fpvalid);
  1829 +}
  1830 +
  1831 +static void bswap_psinfo(struct elf_prpsinfo *psinfo)
  1832 +{
  1833 + psinfo->pr_flag = tswapl(psinfo->pr_flag);
  1834 + psinfo->pr_uid = tswap16(psinfo->pr_uid);
  1835 + psinfo->pr_gid = tswap16(psinfo->pr_gid);
  1836 + psinfo->pr_pid = tswap32(psinfo->pr_pid);
  1837 + psinfo->pr_ppid = tswap32(psinfo->pr_ppid);
  1838 + psinfo->pr_pgrp = tswap32(psinfo->pr_pgrp);
  1839 + psinfo->pr_sid = tswap32(psinfo->pr_sid);
  1840 +}
  1841 +#endif /* BSWAP_NEEDED */
  1842 +
  1843 +/*
  1844 + * Minimal support for linux memory regions. These are needed
  1845 + * when we are finding out what memory exactly belongs to
  1846 + * emulated process. No locks needed here, as long as
  1847 + * thread that received the signal is stopped.
  1848 + */
  1849 +
  1850 +static struct mm_struct *vma_init(void)
  1851 +{
  1852 + struct mm_struct *mm;
  1853 +
  1854 + if ((mm = qemu_malloc(sizeof (*mm))) == NULL)
  1855 + return (NULL);
  1856 +
  1857 + mm->mm_count = 0;
  1858 + TAILQ_INIT(&mm->mm_mmap);
  1859 +
  1860 + return (mm);
  1861 +}
  1862 +
  1863 +static void vma_delete(struct mm_struct *mm)
  1864 +{
  1865 + struct vm_area_struct *vma;
  1866 +
  1867 + while ((vma = vma_first(mm)) != NULL) {
  1868 + TAILQ_REMOVE(&mm->mm_mmap, vma, vma_link);
  1869 + qemu_free(vma);
  1870 + }
  1871 + qemu_free(mm);
  1872 +}
  1873 +
  1874 +static int vma_add_mapping(struct mm_struct *mm, abi_ulong start,
  1875 + abi_ulong end, abi_ulong flags)
  1876 +{
  1877 + struct vm_area_struct *vma;
  1878 +
  1879 + if ((vma = qemu_mallocz(sizeof (*vma))) == NULL)
  1880 + return (-1);
  1881 +
  1882 + vma->vma_start = start;
  1883 + vma->vma_end = end;
  1884 + vma->vma_flags = flags;
  1885 +
  1886 + TAILQ_INSERT_TAIL(&mm->mm_mmap, vma, vma_link);
  1887 + mm->mm_count++;
  1888 +
  1889 + return (0);
  1890 +}
  1891 +
  1892 +static struct vm_area_struct *vma_first(const struct mm_struct *mm)
  1893 +{
  1894 + return (TAILQ_FIRST(&mm->mm_mmap));
  1895 +}
  1896 +
  1897 +static struct vm_area_struct *vma_next(struct vm_area_struct *vma)
  1898 +{
  1899 + return (TAILQ_NEXT(vma, vma_link));
  1900 +}
  1901 +
  1902 +static int vma_get_mapping_count(const struct mm_struct *mm)
  1903 +{
  1904 + return (mm->mm_count);
  1905 +}
  1906 +
  1907 +/*
  1908 + * Calculate file (dump) size of given memory region.
  1909 + */
  1910 +static abi_ulong vma_dump_size(const struct vm_area_struct *vma)
  1911 +{
  1912 + /* if we cannot even read the first page, skip it */
  1913 + if (!access_ok(VERIFY_READ, vma->vma_start, TARGET_PAGE_SIZE))
  1914 + return (0);
  1915 +
  1916 + /*
  1917 + * Usually we don't dump executable pages as they contain
  1918 + * non-writable code that debugger can read directly from
  1919 + * target library etc. However, thread stacks are marked
  1920 + * also executable so we read in first page of given region
  1921 + * and check whether it contains elf header. If there is
  1922 + * no elf header, we dump it.
  1923 + */
  1924 + if (vma->vma_flags & PROT_EXEC) {
  1925 + char page[TARGET_PAGE_SIZE];
  1926 +
  1927 + copy_from_user(page, vma->vma_start, sizeof (page));
  1928 + if ((page[EI_MAG0] == ELFMAG0) &&
  1929 + (page[EI_MAG1] == ELFMAG1) &&
  1930 + (page[EI_MAG2] == ELFMAG2) &&
  1931 + (page[EI_MAG3] == ELFMAG3)) {
  1932 + /*
  1933 + * Mappings are possibly from ELF binary. Don't dump
  1934 + * them.
  1935 + */
  1936 + return (0);
  1937 + }
  1938 + }
  1939 +
  1940 + return (vma->vma_end - vma->vma_start);
  1941 +}
  1942 +
  1943 +static int vma_walker(void *priv, unsigned long start, unsigned long end,
  1944 + unsigned long flags)
  1945 +{
  1946 + struct mm_struct *mm = (struct mm_struct *)priv;
  1947 +
  1948 + /*
  1949 + * Don't dump anything that qemu has reserved for internal use.
  1950 + */
  1951 + if (flags & PAGE_RESERVED)
  1952 + return (0);
  1953 +
  1954 + vma_add_mapping(mm, start, end, flags);
  1955 + return (0);
  1956 +}
  1957 +
  1958 +static void fill_note(struct memelfnote *note, const char *name, int type,
  1959 + unsigned int sz, void *data)
  1960 +{
  1961 + unsigned int namesz;
  1962 +
  1963 + namesz = strlen(name) + 1;
  1964 + note->name = name;
  1965 + note->namesz = namesz;
  1966 + note->namesz_rounded = roundup(namesz, sizeof (int32_t));
  1967 + note->type = type;
  1968 + note->datasz = roundup(sz, sizeof (int32_t));;
  1969 + note->data = data;
  1970 +
  1971 + /*
  1972 + * We calculate rounded up note size here as specified by
  1973 + * ELF document.
  1974 + */
  1975 + note->notesz = sizeof (struct elf_note) +
  1976 + note->namesz_rounded + note->datasz;
  1977 +}
  1978 +
  1979 +static void fill_elf_header(struct elfhdr *elf, int segs, uint16_t machine,
  1980 + uint32_t flags)
  1981 +{
  1982 + (void) memset(elf, 0, sizeof(*elf));
  1983 +
  1984 + (void) memcpy(elf->e_ident, ELFMAG, SELFMAG);
  1985 + elf->e_ident[EI_CLASS] = ELF_CLASS;
  1986 + elf->e_ident[EI_DATA] = ELF_DATA;
  1987 + elf->e_ident[EI_VERSION] = EV_CURRENT;
  1988 + elf->e_ident[EI_OSABI] = ELF_OSABI;
  1989 +
  1990 + elf->e_type = ET_CORE;
  1991 + elf->e_machine = machine;
  1992 + elf->e_version = EV_CURRENT;
  1993 + elf->e_phoff = sizeof(struct elfhdr);
  1994 + elf->e_flags = flags;
  1995 + elf->e_ehsize = sizeof(struct elfhdr);
  1996 + elf->e_phentsize = sizeof(struct elf_phdr);
  1997 + elf->e_phnum = segs;
  1998 +
  1999 +#ifdef BSWAP_NEEDED
  2000 + bswap_ehdr(elf);
  2001 +#endif
  2002 +}
  2003 +
  2004 +static void fill_elf_note_phdr(struct elf_phdr *phdr, int sz, off_t offset)
  2005 +{
  2006 + phdr->p_type = PT_NOTE;
  2007 + phdr->p_offset = offset;
  2008 + phdr->p_vaddr = 0;
  2009 + phdr->p_paddr = 0;
  2010 + phdr->p_filesz = sz;
  2011 + phdr->p_memsz = 0;
  2012 + phdr->p_flags = 0;
  2013 + phdr->p_align = 0;
  2014 +
  2015 +#ifdef BSWAP_NEEDED
  2016 + bswap_phdr(phdr);
  2017 +#endif
  2018 +}
  2019 +
  2020 +static size_t note_size(const struct memelfnote *note)
  2021 +{
  2022 + return (note->notesz);
  2023 +}
  2024 +
  2025 +static void fill_prstatus(struct elf_prstatus *prstatus,
  2026 + const TaskState *ts, int signr)
  2027 +{
  2028 + (void) memset(prstatus, 0, sizeof (*prstatus));
  2029 + prstatus->pr_info.si_signo = prstatus->pr_cursig = signr;
  2030 + prstatus->pr_pid = ts->ts_tid;
  2031 + prstatus->pr_ppid = getppid();
  2032 + prstatus->pr_pgrp = getpgrp();
  2033 + prstatus->pr_sid = getsid(0);
  2034 +
  2035 +#ifdef BSWAP_NEEDED
  2036 + bswap_prstatus(prstatus);
  2037 +#endif
  2038 +}
  2039 +
  2040 +static int fill_psinfo(struct elf_prpsinfo *psinfo, const TaskState *ts)
  2041 +{
  2042 + char *filename, *base_filename;
  2043 + unsigned int i, len;
  2044 +
  2045 + (void) memset(psinfo, 0, sizeof (*psinfo));
  2046 +
  2047 + len = ts->info->arg_end - ts->info->arg_start;
  2048 + if (len >= ELF_PRARGSZ)
  2049 + len = ELF_PRARGSZ - 1;
  2050 + if (copy_from_user(&psinfo->pr_psargs, ts->info->arg_start, len))
  2051 + return -EFAULT;
  2052 + for (i = 0; i < len; i++)
  2053 + if (psinfo->pr_psargs[i] == 0)
  2054 + psinfo->pr_psargs[i] = ' ';
  2055 + psinfo->pr_psargs[len] = 0;
  2056 +
  2057 + psinfo->pr_pid = getpid();
  2058 + psinfo->pr_ppid = getppid();
  2059 + psinfo->pr_pgrp = getpgrp();
  2060 + psinfo->pr_sid = getsid(0);
  2061 + psinfo->pr_uid = getuid();
  2062 + psinfo->pr_gid = getgid();
  2063 +
  2064 + filename = strdup(ts->bprm->filename);
  2065 + base_filename = strdup(basename(filename));
  2066 + (void) strncpy(psinfo->pr_fname, base_filename,
  2067 + sizeof(psinfo->pr_fname));
  2068 + free(base_filename);
  2069 + free(filename);
  2070 +
  2071 +#ifdef BSWAP_NEEDED
  2072 + bswap_psinfo(psinfo);
  2073 +#endif
  2074 + return (0);
  2075 +}
  2076 +
  2077 +static void fill_auxv_note(struct memelfnote *note, const TaskState *ts)
  2078 +{
  2079 + elf_addr_t auxv = (elf_addr_t)ts->info->saved_auxv;
  2080 + elf_addr_t orig_auxv = auxv;
  2081 + abi_ulong val;
  2082 + void *ptr;
  2083 + int i, len;
  2084 +
  2085 + /*
  2086 + * Auxiliary vector is stored in target process stack. It contains
  2087 + * {type, value} pairs that we need to dump into note. This is not
  2088 + * strictly necessary but we do it here for sake of completeness.
  2089 + */
  2090 +
  2091 + /* find out lenght of the vector, AT_NULL is terminator */
  2092 + i = len = 0;
  2093 + do {
  2094 + get_user_ual(val, auxv);
  2095 + i += 2;
  2096 + auxv += 2 * sizeof (elf_addr_t);
  2097 + } while (val != AT_NULL);
  2098 + len = i * sizeof (elf_addr_t);
  2099 +
  2100 + /* read in whole auxv vector and copy it to memelfnote */
  2101 + ptr = lock_user(VERIFY_READ, orig_auxv, len, 0);
  2102 + if (ptr != NULL) {
  2103 + fill_note(note, "CORE", NT_AUXV, len, ptr);
  2104 + unlock_user(ptr, auxv, len);
  2105 + }
  2106 +}
  2107 +
  2108 +/*
  2109 + * Constructs name of coredump file. We have following convention
  2110 + * for the name:
  2111 + * qemu_<basename-of-target-binary>_<date>-<time>_<pid>.core
  2112 + *
  2113 + * Returns 0 in case of success, -1 otherwise (errno is set).
  2114 + */
  2115 +static int core_dump_filename(const TaskState *ts, char *buf,
  2116 + size_t bufsize)
  2117 +{
  2118 + char timestamp[64];
  2119 + char *filename = NULL;
  2120 + char *base_filename = NULL;
  2121 + struct timeval tv;
  2122 + struct tm tm;
  2123 +
  2124 + assert(bufsize >= PATH_MAX);
  2125 +
  2126 + if (gettimeofday(&tv, NULL) < 0) {
  2127 + (void) fprintf(stderr, "unable to get current timestamp: %s",
  2128 + strerror(errno));
  2129 + return (-1);
  2130 + }
  2131 +
  2132 + filename = strdup(ts->bprm->filename);
  2133 + base_filename = strdup(basename(filename));
  2134 + (void) strftime(timestamp, sizeof (timestamp), "%Y%m%d-%H%M%S",
  2135 + localtime_r(&tv.tv_sec, &tm));
  2136 + (void) snprintf(buf, bufsize, "qemu_%s_%s_%d.core",
  2137 + base_filename, timestamp, (int)getpid());
  2138 + free(base_filename);
  2139 + free(filename);
  2140 +
  2141 + return (0);
  2142 +}
  2143 +
  2144 +static int dump_write(int fd, const void *ptr, size_t size)
  2145 +{
  2146 + const char *bufp = (const char *)ptr;
  2147 + ssize_t bytes_written, bytes_left;
  2148 + struct rlimit dumpsize;
  2149 + off_t pos;
  2150 +
  2151 + bytes_written = 0;
  2152 + getrlimit(RLIMIT_CORE, &dumpsize);
  2153 + if ((pos = lseek(fd, 0, SEEK_CUR))==-1) {
  2154 + if (errno == ESPIPE) { /* not a seekable stream */
  2155 + bytes_left = size;
  2156 + } else {
  2157 + return pos;
  2158 + }
  2159 + } else {
  2160 + if (dumpsize.rlim_cur <= pos) {
  2161 + return -1;
  2162 + } else if (dumpsize.rlim_cur == RLIM_INFINITY) {
  2163 + bytes_left = size;
  2164 + } else {
  2165 + size_t limit_left=dumpsize.rlim_cur - pos;
  2166 + bytes_left = limit_left >= size ? size : limit_left ;
  2167 + }
  2168 + }
  2169 +
  2170 + /*
  2171 + * In normal conditions, single write(2) should do but
  2172 + * in case of socket etc. this mechanism is more portable.
  2173 + */
  2174 + do {
  2175 + bytes_written = write(fd, bufp, bytes_left);
  2176 + if (bytes_written < 0) {
  2177 + if (errno == EINTR)
  2178 + continue;
  2179 + return (-1);
  2180 + } else if (bytes_written == 0) { /* eof */
  2181 + return (-1);
  2182 + }
  2183 + bufp += bytes_written;
  2184 + bytes_left -= bytes_written;
  2185 + } while (bytes_left > 0);
  2186 +
  2187 + return (0);
  2188 +}
  2189 +
  2190 +static int write_note(struct memelfnote *men, int fd)
  2191 +{
  2192 + struct elf_note en;
  2193 +
  2194 + en.n_namesz = men->namesz;
  2195 + en.n_type = men->type;
  2196 + en.n_descsz = men->datasz;
  2197 +
  2198 +#ifdef BSWAP_NEEDED
  2199 + bswap_note(&en);
  2200 +#endif
  2201 +
  2202 + if (dump_write(fd, &en, sizeof(en)) != 0)
  2203 + return (-1);
  2204 + if (dump_write(fd, men->name, men->namesz_rounded) != 0)
  2205 + return (-1);
  2206 + if (dump_write(fd, men->data, men->datasz) != 0)
  2207 + return (-1);
  2208 +
  2209 + return (0);
  2210 +}
  2211 +
  2212 +static void fill_thread_info(struct elf_note_info *info, const CPUState *env)
  2213 +{
  2214 + TaskState *ts = (TaskState *)env->opaque;
  2215 + struct elf_thread_status *ets;
  2216 +
  2217 + ets = qemu_mallocz(sizeof (*ets));
  2218 + ets->num_notes = 1; /* only prstatus is dumped */
  2219 + fill_prstatus(&ets->prstatus, ts, 0);
  2220 + elf_core_copy_regs(&ets->prstatus.pr_reg, env);
  2221 + fill_note(&ets->notes[0], "CORE", NT_PRSTATUS, sizeof (ets->prstatus),
  2222 + &ets->prstatus);
  2223 +
  2224 + TAILQ_INSERT_TAIL(&info->thread_list, ets, ets_link);
  2225 +
  2226 + info->notes_size += note_size(&ets->notes[0]);
  2227 +}
  2228 +
  2229 +static int fill_note_info(struct elf_note_info *info,
  2230 + long signr, const CPUState *env)
  2231 +{
  2232 +#define NUMNOTES 3
  2233 + CPUState *cpu = NULL;
  2234 + TaskState *ts = (TaskState *)env->opaque;
  2235 + int i;
  2236 +
  2237 + (void) memset(info, 0, sizeof (*info));
  2238 +
  2239 + TAILQ_INIT(&info->thread_list);
  2240 +
  2241 + info->notes = qemu_mallocz(NUMNOTES * sizeof (struct memelfnote));
  2242 + if (info->notes == NULL)
  2243 + return (-ENOMEM);
  2244 + info->prstatus = qemu_mallocz(sizeof (*info->prstatus));
  2245 + if (info->prstatus == NULL)
  2246 + return (-ENOMEM);
  2247 + info->psinfo = qemu_mallocz(sizeof (*info->psinfo));
  2248 + if (info->prstatus == NULL)
  2249 + return (-ENOMEM);
  2250 +
  2251 + /*
  2252 + * First fill in status (and registers) of current thread
  2253 + * including process info & aux vector.
  2254 + */
  2255 + fill_prstatus(info->prstatus, ts, signr);
  2256 + elf_core_copy_regs(&info->prstatus->pr_reg, env);
  2257 + fill_note(&info->notes[0], "CORE", NT_PRSTATUS,
  2258 + sizeof (*info->prstatus), info->prstatus);
  2259 + fill_psinfo(info->psinfo, ts);
  2260 + fill_note(&info->notes[1], "CORE", NT_PRPSINFO,
  2261 + sizeof (*info->psinfo), info->psinfo);
  2262 + fill_auxv_note(&info->notes[2], ts);
  2263 + info->numnote = 3;
  2264 +
  2265 + info->notes_size = 0;
  2266 + for (i = 0; i < info->numnote; i++)
  2267 + info->notes_size += note_size(&info->notes[i]);
  2268 +
  2269 + /* read and fill status of all threads */
  2270 + cpu_list_lock();
  2271 + for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
  2272 + if (cpu == thread_env)
  2273 + continue;
  2274 + fill_thread_info(info, cpu);
  2275 + }
  2276 + cpu_list_unlock();
  2277 +
  2278 + return (0);
  2279 +}
  2280 +
  2281 +static void free_note_info(struct elf_note_info *info)
  2282 +{
  2283 + struct elf_thread_status *ets;
  2284 +
  2285 + while (!TAILQ_EMPTY(&info->thread_list)) {
  2286 + ets = TAILQ_FIRST(&info->thread_list);
  2287 + TAILQ_REMOVE(&info->thread_list, ets, ets_link);
  2288 + qemu_free(ets);
  2289 + }
  2290 +
  2291 + qemu_free(info->prstatus);
  2292 + qemu_free(info->psinfo);
  2293 + qemu_free(info->notes);
  2294 +}
  2295 +
  2296 +static int write_note_info(struct elf_note_info *info, int fd)
  2297 +{
  2298 + struct elf_thread_status *ets;
  2299 + int i, error = 0;
  2300 +
  2301 + /* write prstatus, psinfo and auxv for current thread */
  2302 + for (i = 0; i < info->numnote; i++)
  2303 + if ((error = write_note(&info->notes[i], fd)) != 0)
  2304 + return (error);
  2305 +
  2306 + /* write prstatus for each thread */
  2307 + for (ets = info->thread_list.tqh_first; ets != NULL;
  2308 + ets = ets->ets_link.tqe_next) {
  2309 + if ((error = write_note(&ets->notes[0], fd)) != 0)
  2310 + return (error);
  2311 + }
  2312 +
  2313 + return (0);
  2314 +}
  2315 +
  2316 +/*
  2317 + * Write out ELF coredump.
  2318 + *
  2319 + * See documentation of ELF object file format in:
  2320 + * http://www.caldera.com/developers/devspecs/gabi41.pdf
  2321 + *
  2322 + * Coredump format in linux is following:
  2323 + *
  2324 + * 0 +----------------------+ \
  2325 + * | ELF header | ET_CORE |
  2326 + * +----------------------+ |
  2327 + * | ELF program headers | |--- headers
  2328 + * | - NOTE section | |
  2329 + * | - PT_LOAD sections | |
  2330 + * +----------------------+ /
  2331 + * | NOTEs: |
  2332 + * | - NT_PRSTATUS |
  2333 + * | - NT_PRSINFO |
  2334 + * | - NT_AUXV |
  2335 + * +----------------------+ <-- aligned to target page
  2336 + * | Process memory dump |
  2337 + * : :
  2338 + * . .
  2339 + * : :
  2340 + * | |
  2341 + * +----------------------+
  2342 + *
  2343 + * NT_PRSTATUS -> struct elf_prstatus (per thread)
  2344 + * NT_PRSINFO -> struct elf_prpsinfo
  2345 + * NT_AUXV is array of { type, value } pairs (see fill_auxv_note()).
  2346 + *
  2347 + * Format follows System V format as close as possible. Current
  2348 + * version limitations are as follows:
  2349 + * - no floating point registers are dumped
  2350 + *
  2351 + * Function returns 0 in case of success, negative errno otherwise.
  2352 + *
  2353 + * TODO: make this work also during runtime: it should be
  2354 + * possible to force coredump from running process and then
  2355 + * continue processing. For example qemu could set up SIGUSR2
  2356 + * handler (provided that target process haven't registered
  2357 + * handler for that) that does the dump when signal is received.
  2358 + */
  2359 +static int elf_core_dump(int signr, const CPUState *env)
  2360 +{
  2361 + const TaskState *ts = (const TaskState *)env->opaque;
  2362 + struct vm_area_struct *vma = NULL;
  2363 + char corefile[PATH_MAX];
  2364 + struct elf_note_info info;
  2365 + struct elfhdr elf;
  2366 + struct elf_phdr phdr;
  2367 + struct rlimit dumpsize;
  2368 + struct mm_struct *mm = NULL;
  2369 + off_t offset = 0, data_offset = 0;
  2370 + int segs = 0;
  2371 + int fd = -1;
  2372 +
  2373 + errno = 0;
  2374 + getrlimit(RLIMIT_CORE, &dumpsize);
  2375 + if (dumpsize.rlim_cur == 0)
  2376 + return 0;
  2377 +
  2378 + if (core_dump_filename(ts, corefile, sizeof (corefile)) < 0)
  2379 + return (-errno);
  2380 +
  2381 + if ((fd = open(corefile, O_WRONLY | O_CREAT,
  2382 + S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0)
  2383 + return (-errno);
  2384 +
  2385 + /*
  2386 + * Walk through target process memory mappings and
  2387 + * set up structure containing this information. After
  2388 + * this point vma_xxx functions can be used.
  2389 + */
  2390 + if ((mm = vma_init()) == NULL)
  2391 + goto out;
  2392 +
  2393 + walk_memory_regions(mm, vma_walker);
  2394 + segs = vma_get_mapping_count(mm);
  2395 +
  2396 + /*
  2397 + * Construct valid coredump ELF header. We also
  2398 + * add one more segment for notes.
  2399 + */
  2400 + fill_elf_header(&elf, segs + 1, ELF_MACHINE, 0);
  2401 + if (dump_write(fd, &elf, sizeof (elf)) != 0)
  2402 + goto out;
  2403 +
  2404 + /* fill in in-memory version of notes */
  2405 + if (fill_note_info(&info, signr, env) < 0)
  2406 + goto out;
  2407 +
  2408 + offset += sizeof (elf); /* elf header */
  2409 + offset += (segs + 1) * sizeof (struct elf_phdr); /* program headers */
  2410 +
  2411 + /* write out notes program header */
  2412 + fill_elf_note_phdr(&phdr, info.notes_size, offset);
  2413 +
  2414 + offset += info.notes_size;
  2415 + if (dump_write(fd, &phdr, sizeof (phdr)) != 0)
  2416 + goto out;
  2417 +
  2418 + /*
  2419 + * ELF specification wants data to start at page boundary so
  2420 + * we align it here.
  2421 + */
  2422 + offset = roundup(offset, ELF_EXEC_PAGESIZE);
  2423 +
  2424 + /*
  2425 + * Write program headers for memory regions mapped in
  2426 + * the target process.
  2427 + */
  2428 + for (vma = vma_first(mm); vma != NULL; vma = vma_next(vma)) {
  2429 + (void) memset(&phdr, 0, sizeof (phdr));
  2430 +
  2431 + phdr.p_type = PT_LOAD;
  2432 + phdr.p_offset = offset;
  2433 + phdr.p_vaddr = vma->vma_start;
  2434 + phdr.p_paddr = 0;
  2435 + phdr.p_filesz = vma_dump_size(vma);
  2436 + offset += phdr.p_filesz;
  2437 + phdr.p_memsz = vma->vma_end - vma->vma_start;
  2438 + phdr.p_flags = vma->vma_flags & PROT_READ ? PF_R : 0;
  2439 + if (vma->vma_flags & PROT_WRITE)
  2440 + phdr.p_flags |= PF_W;
  2441 + if (vma->vma_flags & PROT_EXEC)
  2442 + phdr.p_flags |= PF_X;
  2443 + phdr.p_align = ELF_EXEC_PAGESIZE;
  2444 +
  2445 + dump_write(fd, &phdr, sizeof (phdr));
  2446 + }
  2447 +
  2448 + /*
  2449 + * Next we write notes just after program headers. No
  2450 + * alignment needed here.
  2451 + */
  2452 + if (write_note_info(&info, fd) < 0)
  2453 + goto out;
  2454 +
  2455 + /* align data to page boundary */
  2456 + data_offset = lseek(fd, 0, SEEK_CUR);
  2457 + data_offset = TARGET_PAGE_ALIGN(data_offset);
  2458 + if (lseek(fd, data_offset, SEEK_SET) != data_offset)
  2459 + goto out;
  2460 +
  2461 + /*
  2462 + * Finally we can dump process memory into corefile as well.
  2463 + */
  2464 + for (vma = vma_first(mm); vma != NULL; vma = vma_next(vma)) {
  2465 + abi_ulong addr;
  2466 + abi_ulong end;
  2467 +
  2468 + end = vma->vma_start + vma_dump_size(vma);
  2469 +
  2470 + for (addr = vma->vma_start; addr < end;
  2471 + addr += TARGET_PAGE_SIZE) {
  2472 + char page[TARGET_PAGE_SIZE];
  2473 + int error;
  2474 +
  2475 + /*
  2476 + * Read in page from target process memory and
  2477 + * write it to coredump file.
  2478 + */
  2479 + error = copy_from_user(page, addr, sizeof (page));
  2480 + if (error != 0) {
  2481 + (void) fprintf(stderr, "unable to dump " TARGET_FMT_lx "\n",
  2482 + addr);
  2483 + errno = -error;
  2484 + goto out;
  2485 + }
  2486 + if (dump_write(fd, page, TARGET_PAGE_SIZE) < 0)
  2487 + goto out;
  2488 + }
  2489 + }
  2490 +
  2491 +out:
  2492 + free_note_info(&info);
  2493 + if (mm != NULL)
  2494 + vma_delete(mm);
  2495 + (void) close(fd);
  2496 +
  2497 + if (errno != 0)
  2498 + return (-errno);
  2499 + return (0);
  2500 +}
  2501 +
  2502 +#endif /* USE_ELF_CORE_DUMP */
  2503 +
1592 2504 static int load_aout_interp(void * exptr, int interp_fd)
1593 2505 {
1594 2506 printf("a.out interpreter not yet supported\n");
... ...
linux-user/linuxload.c
... ... @@ -115,6 +115,7 @@ static int prepare_binprm(struct linux_binprm *bprm)
115 115 abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp,
116 116 abi_ulong stringp, int push_ptr)
117 117 {
  118 + TaskState *ts = (TaskState *)thread_env->opaque;
118 119 int n = sizeof(abi_ulong);
119 120 abi_ulong envp;
120 121 abi_ulong argv;
... ... @@ -133,13 +134,14 @@ abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp,
133 134 sp -= n;
134 135 /* FIXME - handle put_user() failures */
135 136 put_user_ual(argc, sp);
136   -
  137 + ts->info->arg_start = stringp;
137 138 while (argc-- > 0) {
138 139 /* FIXME - handle put_user() failures */
139 140 put_user_ual(stringp, argv);
140 141 argv += n;
141 142 stringp += target_strlen(stringp) + 1;
142 143 }
  144 + ts->info->arg_end = stringp;
143 145 /* FIXME - handle put_user() failures */
144 146 put_user_ual(0, argv);
145 147 while (envc-- > 0) {
... ... @@ -155,45 +157,45 @@ abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp,
155 157 }
156 158  
157 159 int loader_exec(const char * filename, char ** argv, char ** envp,
158   - struct target_pt_regs * regs, struct image_info *infop)
  160 + struct target_pt_regs * regs, struct image_info *infop,
  161 + struct linux_binprm *bprm)
159 162 {
160   - struct linux_binprm bprm;
161 163 int retval;
162 164 int i;
163 165  
164   - bprm.p = TARGET_PAGE_SIZE*MAX_ARG_PAGES-sizeof(unsigned int);
  166 + bprm->p = TARGET_PAGE_SIZE*MAX_ARG_PAGES-sizeof(unsigned int);
165 167 for (i=0 ; i<MAX_ARG_PAGES ; i++) /* clear page-table */
166   - bprm.page[i] = 0;
  168 + bprm->page[i] = 0;
167 169 retval = open(filename, O_RDONLY);
168 170 if (retval < 0)
169 171 return retval;
170   - bprm.fd = retval;
171   - bprm.filename = (char *)filename;
172   - bprm.argc = count(argv);
173   - bprm.argv = argv;
174   - bprm.envc = count(envp);
175   - bprm.envp = envp;
  172 + bprm->fd = retval;
  173 + bprm->filename = (char *)filename;
  174 + bprm->argc = count(argv);
  175 + bprm->argv = argv;
  176 + bprm->envc = count(envp);
  177 + bprm->envp = envp;
176 178  
177   - retval = prepare_binprm(&bprm);
  179 + retval = prepare_binprm(bprm);
178 180  
179 181 infop->host_argv = argv;
180 182  
181 183 if(retval>=0) {
182   - if (bprm.buf[0] == 0x7f
183   - && bprm.buf[1] == 'E'
184   - && bprm.buf[2] == 'L'
185   - && bprm.buf[3] == 'F') {
  184 + if (bprm->buf[0] == 0x7f
  185 + && bprm->buf[1] == 'E'
  186 + && bprm->buf[2] == 'L'
  187 + && bprm->buf[3] == 'F') {
186 188 #ifndef TARGET_HAS_ELFLOAD32
187   - retval = load_elf_binary(&bprm,regs,infop);
  189 + retval = load_elf_binary(bprm,regs,infop);
188 190 #else
189   - retval = load_elf_binary_multi(&bprm, regs, infop);
  191 + retval = load_elf_binary_multi(bprm, regs, infop);
190 192 #endif
191 193 #if defined(TARGET_HAS_BFLT)
192   - } else if (bprm.buf[0] == 'b'
193   - && bprm.buf[1] == 'F'
194   - && bprm.buf[2] == 'L'
195   - && bprm.buf[3] == 'T') {
196   - retval = load_flt_binary(&bprm,regs,infop);
  194 + } else if (bprm->buf[0] == 'b'
  195 + && bprm->buf[1] == 'F'
  196 + && bprm->buf[2] == 'L'
  197 + && bprm->buf[3] == 'T') {
  198 + retval = load_flt_binary(bprm,regs,infop);
197 199 #endif
198 200 } else {
199 201 fprintf(stderr, "Unknown binary format\n");
... ... @@ -209,7 +211,7 @@ int loader_exec(const char * filename, char ** argv, char ** envp,
209 211  
210 212 /* Something went wrong, return the inode and free the argument pages*/
211 213 for (i=0 ; i<MAX_ARG_PAGES ; i++) {
212   - free(bprm.page[i]);
  214 + free(bprm->page[i]);
213 215 }
214 216 return(retval);
215 217 }
... ...
linux-user/main.c
... ... @@ -25,6 +25,7 @@
25 25 #include <errno.h>
26 26 #include <unistd.h>
27 27 #include <sys/mman.h>
  28 +#include <sys/syscall.h>
28 29  
29 30 #include "qemu.h"
30 31 #include "qemu-common.h"
... ... @@ -2319,6 +2320,27 @@ static void usage(void)
2319 2320  
2320 2321 THREAD CPUState *thread_env;
2321 2322  
  2323 +void task_settid(TaskState *ts)
  2324 +{
  2325 + if (ts->ts_tid == 0) {
  2326 +#ifdef USE_NPTL
  2327 + ts->ts_tid = (pid_t)syscall(SYS_gettid);
  2328 +#else
  2329 + /* when no threads are used, tid becomes pid */
  2330 + ts->ts_tid = getpid();
  2331 +#endif
  2332 + }
  2333 +}
  2334 +
  2335 +void stop_all_tasks(void)
  2336 +{
  2337 + /*
  2338 + * We trust that when using NPTL, start_exclusive()
  2339 + * handles thread stopping correctly.
  2340 + */
  2341 + start_exclusive();
  2342 +}
  2343 +
2322 2344 /* Assumes contents are already zeroed. */
2323 2345 void init_task_state(TaskState *ts)
2324 2346 {
... ... @@ -2338,6 +2360,7 @@ int main(int argc, char **argv, char **envp)
2338 2360 const char *cpu_model;
2339 2361 struct target_pt_regs regs1, *regs = &regs1;
2340 2362 struct image_info info1, *info = &info1;
  2363 + struct linux_binprm bprm;
2341 2364 TaskState ts1, *ts = &ts1;
2342 2365 CPUState *env;
2343 2366 int optind;
... ... @@ -2467,6 +2490,8 @@ int main(int argc, char **argv, char **envp)
2467 2490 /* Zero out image_info */
2468 2491 memset(info, 0, sizeof(struct image_info));
2469 2492  
  2493 + memset(&bprm, 0, sizeof (bprm));
  2494 +
2470 2495 /* Scan interp_prefix dir for replacement files. */
2471 2496 init_paths(interp_prefix);
2472 2497  
... ... @@ -2543,7 +2568,16 @@ int main(int argc, char **argv, char **envp)
2543 2568 }
2544 2569 target_argv[target_argc] = NULL;
2545 2570  
2546   - if (loader_exec(filename, target_argv, target_environ, regs, info) != 0) {
  2571 + memset(ts, 0, sizeof(TaskState));
  2572 + init_task_state(ts);
  2573 + /* build Task State */
  2574 + ts->info = info;
  2575 + ts->bprm = &bprm;
  2576 + env->opaque = ts;
  2577 + task_settid(ts);
  2578 +
  2579 + if (loader_exec(filename, target_argv, target_environ, regs,
  2580 + info, &bprm) != 0) {
2547 2581 printf("Error loading %s\n", filename);
2548 2582 _exit(1);
2549 2583 }
... ... @@ -2579,12 +2613,6 @@ int main(int argc, char **argv, char **envp)
2579 2613 syscall_init();
2580 2614 signal_init();
2581 2615  
2582   - /* build Task State */
2583   - memset(ts, 0, sizeof(TaskState));
2584   - init_task_state(ts);
2585   - ts->info = info;
2586   - env->opaque = ts;
2587   -
2588 2616 #if defined(TARGET_I386)
2589 2617 cpu_x86_set_cpl(env, 3);
2590 2618  
... ...
linux-user/qemu.h
... ... @@ -18,6 +18,7 @@
18 18 #include "syscall.h"
19 19 #include "target_signal.h"
20 20 #include "gdbstub.h"
  21 +#include "sys-queue.h"
21 22  
22 23 #if defined(USE_NPTL)
23 24 #define THREAD __thread
... ... @@ -44,6 +45,9 @@ struct image_info {
44 45 abi_ulong entry;
45 46 abi_ulong code_offset;
46 47 abi_ulong data_offset;
  48 + abi_ulong saved_auxv;
  49 + abi_ulong arg_start;
  50 + abi_ulong arg_end;
47 51 char **host_argv;
48 52 int personality;
49 53 };
... ... @@ -87,7 +91,7 @@ struct emulated_sigtable {
87 91 /* NOTE: we force a big alignment so that the stack stored after is
88 92 aligned too */
89 93 typedef struct TaskState {
90   - struct TaskState *next;
  94 + pid_t ts_tid; /* tid (or pid) of this task */
91 95 #ifdef TARGET_ARM
92 96 /* FPA state */
93 97 FPA11 fpa;
... ... @@ -114,6 +118,7 @@ typedef struct TaskState {
114 118 #endif
115 119 int used; /* non zero if used */
116 120 struct image_info *info;
  121 + struct linux_binprm *bprm;
117 122  
118 123 struct emulated_sigtable sigtab[TARGET_NSIG];
119 124 struct sigqueue sigqueue_table[MAX_SIGQUEUE_SIZE]; /* siginfo queue */
... ... @@ -125,6 +130,8 @@ typedef struct TaskState {
125 130  
126 131 extern char *exec_path;
127 132 void init_task_state(TaskState *ts);
  133 +void task_settid(TaskState *);
  134 +void stop_all_tasks(void);
128 135 extern const char *qemu_uname_release;
129 136  
130 137 /* ??? See if we can avoid exposing so much of the loader internals. */
... ... @@ -149,13 +156,15 @@ struct linux_binprm {
149 156 char **argv;
150 157 char **envp;
151 158 char * filename; /* Name of binary */
  159 + int (*core_dump)(int, const CPUState *); /* coredump routine */
152 160 };
153 161  
154 162 void do_init_thread(struct target_pt_regs *regs, struct image_info *infop);
155 163 abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp,
156 164 abi_ulong stringp, int push_ptr);
157 165 int loader_exec(const char * filename, char ** argv, char ** envp,
158   - struct target_pt_regs * regs, struct image_info *infop);
  166 + struct target_pt_regs * regs, struct image_info *infop,
  167 + struct linux_binprm *);
159 168  
160 169 int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
161 170 struct image_info * info);
... ...
linux-user/signal.c
... ... @@ -27,6 +27,7 @@
27 27 #include <errno.h>
28 28 #include <assert.h>
29 29 #include <sys/ucontext.h>
  30 +#include <sys/resource.h>
30 31  
31 32 #include "qemu.h"
32 33 #include "qemu-common.h"
... ... @@ -287,6 +288,23 @@ static int fatal_signal (int sig)
287 288 }
288 289 }
289 290  
  291 +/* returns 1 if given signal should dump core if not handled */
  292 +static int core_dump_signal(int sig)
  293 +{
  294 + switch (sig) {
  295 + case TARGET_SIGABRT:
  296 + case TARGET_SIGFPE:
  297 + case TARGET_SIGILL:
  298 + case TARGET_SIGQUIT:
  299 + case TARGET_SIGSEGV:
  300 + case TARGET_SIGTRAP:
  301 + case TARGET_SIGBUS:
  302 + return (1);
  303 + default:
  304 + return (0);
  305 + }
  306 +}
  307 +
290 308 void signal_init(void)
291 309 {
292 310 struct sigaction act;
... ... @@ -352,13 +370,29 @@ static inline void free_sigqueue(CPUState *env, struct sigqueue *q)
352 370 /* abort execution with signal */
353 371 static void QEMU_NORETURN force_sig(int sig)
354 372 {
355   - int host_sig;
  373 + TaskState *ts = (TaskState *)thread_env->opaque;
  374 + int host_sig, core_dumped = 0;
356 375 struct sigaction act;
357 376 host_sig = target_to_host_signal(sig);
358   - fprintf(stderr, "qemu: uncaught target signal %d (%s) - exiting\n",
359   - sig, strsignal(host_sig));
360 377 gdb_signalled(thread_env, sig);
361 378  
  379 + /* dump core if supported by target binary format */
  380 + if (core_dump_signal(sig) && (ts->bprm->core_dump != NULL)) {
  381 + stop_all_tasks();
  382 + core_dumped =
  383 + ((*ts->bprm->core_dump)(sig, thread_env) == 0);
  384 + }
  385 + if (core_dumped) {
  386 + /* we already dumped the core of target process, we don't want
  387 + * a coredump of qemu itself */
  388 + struct rlimit nodump;
  389 + getrlimit(RLIMIT_CORE, &nodump);
  390 + nodump.rlim_cur=0;
  391 + setrlimit(RLIMIT_CORE, &nodump);
  392 + (void) fprintf(stderr, "qemu: uncaught target signal %d (%s) - %s\n",
  393 + sig, strsignal(host_sig), "core dumped" );
  394 + }
  395 +
362 396 /* The proper exit code for dieing from an uncaught signal is
363 397 * -<signal>. The kernel doesn't allow exit() or _exit() to pass
364 398 * a negative value. To get the proper exit code we need to
... ...
linux-user/syscall.c
... ... @@ -3379,11 +3379,14 @@ static void *clone_func(void *arg)
3379 3379 {
3380 3380 new_thread_info *info = arg;
3381 3381 CPUState *env;
  3382 + TaskState *ts;
3382 3383  
3383 3384 env = info->env;
3384 3385 thread_env = env;
  3386 + ts = (TaskState *)thread_env->opaque;
3385 3387 info->tid = gettid();
3386 3388 env->host_tid = info->tid;
  3389 + task_settid(ts);
3387 3390 if (info->child_tidptr)
3388 3391 put_user_u32(info->tid, info->child_tidptr);
3389 3392 if (info->parent_tidptr)
... ... @@ -3435,6 +3438,7 @@ static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
3435 3438 flags &= ~(CLONE_VFORK | CLONE_VM);
3436 3439  
3437 3440 if (flags & CLONE_VM) {
  3441 + TaskState *parent_ts = (TaskState *)env->opaque;
3438 3442 #if defined(USE_NPTL)
3439 3443 new_thread_info info;
3440 3444 pthread_attr_t attr;
... ... @@ -3447,6 +3451,8 @@ static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
3447 3451 /* Init regs that differ from the parent. */
3448 3452 cpu_clone_regs(new_env, newsp);
3449 3453 new_env->opaque = ts;
  3454 + ts->bprm = parent_ts->bprm;
  3455 + ts->info = parent_ts->info;
3450 3456 #if defined(USE_NPTL)
3451 3457 nptl_flags = flags;
3452 3458 flags &= ~CLONE_NPTL_FLAGS2;
... ...