summaryrefslogtreecommitdiff
path: root/exec.c
diff options
context:
space:
mode:
authorMika Westerberg <mika.westerberg@iki.fi>2009-04-07 09:57:11 +0300
committerRiku Voipio <riku.voipio@nokia.com>2009-06-16 16:56:28 +0300
commitedf8e2af1453ce56c72b2f25a745e3734177a05d (patch)
tree367df4d32d3d75137076cd38738199d4d5b27901 /exec.c
parent88a8c98455cc28ef27f92fd0c6845cedf86d21fc (diff)
downloadqemu-edf8e2af1453ce56c72b2f25a745e3734177a05d.tar.gz
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.c69
1 files changed, 46 insertions, 23 deletions
diff --git a/exec.c b/exec.c
index 52f4e89251..9e7d66ac52 100644
--- a/exec.c
+++ b/exec.c
@@ -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)