diff options
author | Mika Westerberg <mika.westerberg@iki.fi> | 2009-04-07 09:57:11 +0300 |
---|---|---|
committer | Riku Voipio <riku.voipio@nokia.com> | 2009-06-16 16:56:28 +0300 |
commit | edf8e2af1453ce56c72b2f25a745e3734177a05d (patch) | |
tree | 367df4d32d3d75137076cd38738199d4d5b27901 /exec.c | |
parent | 88a8c98455cc28ef27f92fd0c6845cedf86d21fc (diff) |
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>
Diffstat (limited to 'exec.c')
-rw-r--r-- | exec.c | 69 |
1 files changed, 46 insertions, 23 deletions
@@ -2131,36 +2131,36 @@ int tlb_set_page_exec(CPUState *env, target_ulong vaddr, return 0; } -/* dump memory mappings */ -void page_dump(FILE *f) +/* + * Walks guest process memory "regions" one by one + * and calls callback function 'fn' for each region. + */ +int walk_memory_regions(void *priv, + int (*fn)(void *, unsigned long, unsigned long, unsigned long)) { unsigned long start, end; + PageDesc *p = NULL; int i, j, prot, prot1; - PageDesc *p; + int rc = 0; - fprintf(f, "%-8s %-8s %-8s %s\n", - "start", "end", "size", "prot"); - start = -1; - end = -1; + start = end = -1; prot = 0; - for(i = 0; i <= L1_SIZE; i++) { - if (i < L1_SIZE) - p = l1_map[i]; - else - p = NULL; - for(j = 0;j < L2_SIZE; j++) { - if (!p) - prot1 = 0; - else - prot1 = p[j].flags; + + for (i = 0; i <= L1_SIZE; i++) { + p = (i < L1_SIZE) ? l1_map[i] : NULL; + for (j = 0; j < L2_SIZE; j++) { + prot1 = (p == NULL) ? 0 : p[j].flags; + /* + * "region" is one continuous chunk of memory + * that has same protection flags set. + */ if (prot1 != prot) { end = (i << (32 - L1_BITS)) | (j << TARGET_PAGE_BITS); if (start != -1) { - fprintf(f, "%08lx-%08lx %08lx %c%c%c\n", - start, end, end - start, - prot & PAGE_READ ? 'r' : '-', - prot & PAGE_WRITE ? 'w' : '-', - prot & PAGE_EXEC ? 'x' : '-'); + rc = (*fn)(priv, start, end, prot); + /* callback can stop iteration by returning != 0 */ + if (rc != 0) + return (rc); } if (prot1 != 0) start = end; @@ -2168,10 +2168,33 @@ void page_dump(FILE *f) start = -1; prot = prot1; } - if (!p) + if (p == NULL) break; } } + return (rc); +} + +static int dump_region(void *priv, unsigned long start, + unsigned long end, unsigned long prot) +{ + FILE *f = (FILE *)priv; + + (void) fprintf(f, "%08lx-%08lx %08lx %c%c%c\n", + start, end, end - start, + ((prot & PAGE_READ) ? 'r' : '-'), + ((prot & PAGE_WRITE) ? 'w' : '-'), + ((prot & PAGE_EXEC) ? 'x' : '-')); + + return (0); +} + +/* dump memory mappings */ +void page_dump(FILE *f) +{ + (void) fprintf(f, "%-8s %-8s %-8s %s\n", + "start", "end", "size", "prot"); + walk_memory_regions(f, dump_region); } int page_get_flags(target_ulong address) |