eclair: support for multiple physical memory chunks

This commit is contained in:
Balazs Gerofi
2016-10-03 17:24:48 -04:00
parent 1e8239d72a
commit f33d85a27a

View File

@@ -17,6 +17,20 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <arpa/inet.h> #include <arpa/inet.h>
/* From ihk/linux/include/ihk/ihk_host_user.h */
#define PHYS_CHUNKS_DESC_SIZE 8192
struct dump_mem_chunk {
unsigned long addr;
unsigned long size;
};
typedef struct dump_mem_chunks_s {
int nr_chunks;
struct dump_mem_chunk chunks[];
} dump_mem_chunks_t;
/* ---------- */
#define CPU_TID_BASE 1000000 #define CPU_TID_BASE 1000000
struct options { struct options {
@@ -53,6 +67,7 @@ static volatile int f_done = 0;
static bfd *symbfd = NULL; static bfd *symbfd = NULL;
static bfd *dumpbfd = NULL; static bfd *dumpbfd = NULL;
static asection *dumpscn = NULL; static asection *dumpscn = NULL;
static dump_mem_chunks_t *mem_chunks;
static int num_processors = -1; static int num_processors = -1;
static asymbol **symtab = NULL; static asymbol **symtab = NULL;
static ssize_t nsyms; static ssize_t nsyms;
@@ -91,25 +106,35 @@ static uintptr_t virt_to_phys(uintptr_t va) {
static int read_physmem(uintptr_t pa, void *buf, size_t size) { static int read_physmem(uintptr_t pa, void *buf, size_t size) {
off_t off; off_t off;
bfd_boolean ok; bfd_boolean ok;
int i;
if (pa < dumpscn->vma) { off = 0;
printf("read_physmem(%lx,%p,%lx):too small pa. vma %lx\n", pa, buf, size, dumpscn->vma); /* Check if pa is valid in any chunks and figure
return 1; * out the global offset in dump section */
} for (i = 0; i < mem_chunks->nr_chunks; ++i) {
off = pa - dumpscn->vma;
if (off >= dumpscn->size) { if (mem_chunks->chunks[i].addr <= pa &&
printf("read_physmem(%lx,%p,%lx):too large pa. vma %lx size %lx\n", pa, buf, size, dumpscn->vma, dumpscn->size); ((pa + size) <= (mem_chunks->chunks[i].addr +
return 1; mem_chunks->chunks[i].size))) {
}
if ((dumpscn->size - off) < size) { off += (pa - mem_chunks->chunks[i].addr);
printf("read_physmem(%lx,%p,%lx):too large size. vma %lx size %lx\n", pa, buf, size, dumpscn->vma, dumpscn->size); break;
}
off += mem_chunks->chunks[i].size;
}
if (i == mem_chunks->nr_chunks) {
printf("read_physmem: invalid addr 0x%lx\n", pa);
return 1; return 1;
} }
ok = bfd_get_section_contents(dumpbfd, dumpscn, buf, off, size); ok = bfd_get_section_contents(dumpbfd, dumpscn, buf, off, size);
if (!ok) { if (!ok) {
bfd_perror("read_physmem:bfd_get_section_contents"); bfd_perror("read_physmem:bfd_get_section_contents");
return 1; return 1;
} }
return 0; return 0;
} /* read_physmem() */ } /* read_physmem() */
@@ -508,6 +533,25 @@ static int setup_dump(char *fname) {
return 1; return 1;
} }
mem_chunks = malloc(PHYS_CHUNKS_DESC_SIZE);
if (!mem_chunks) {
perror("allocating mem chunks descriptor: ");
return 1;
}
dumpscn = bfd_get_section_by_name(dumpbfd, "physchunks");
if (!dumpscn) {
bfd_perror("bfd_get_section_by_name");
return 1;
}
ok = bfd_get_section_contents(dumpbfd, dumpscn, mem_chunks,
0, PHYS_CHUNKS_DESC_SIZE);
if (!ok) {
bfd_perror("read_physmem:bfd_get_section_contents");
return 1;
}
dumpscn = bfd_get_section_by_name(dumpbfd, "physmem"); dumpscn = bfd_get_section_by_name(dumpbfd, "physmem");
if (!dumpscn) { if (!dumpscn) {
bfd_perror("bfd_get_section_by_name"); bfd_perror("bfd_get_section_by_name");