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>
This commit is contained in:
Mika Westerberg 2009-04-07 09:57:11 +03:00 committed by Riku Voipio
parent 88a8c98455
commit edf8e2af14
9 changed files with 1101 additions and 68 deletions

69
exec.c
View file

@ -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)