Hi.
A new makedumpfile can handle both ELF32 and ELF64 vmcore.
The existing makedumpfile handles /proc/vmcore as ELF64 though user
can specify ELF32 or ELF64 on i386. If user specifies ELF32 vmcore
when 2nd-kernel is loaded, makedumpfile cannot create the dumpfile
correctly.
Thanks
Ken'ichi Ohmichi
diff -puN backup/v1.0.6/makedumpfile.c makedumpfile/makedumpfile.c
--- backup/v1.0.6/makedumpfile.c 2006-11-27 15:50:15.000000000 +0900
+++ makedumpfile/makedumpfile.c 2006-12-04 22:07:07.000000000 +0900
@@ -481,7 +481,7 @@ open_files_for_creating_dumpfile(struct
}
int
-dump_Elf_pt_load(struct DumpInfo *info, GElf_Phdr *prog, int num_load)
+dump_Elf64_load(struct DumpInfo *info, Elf64_Phdr *prog, int num_load)
{
struct pt_load_segment *pls;
@@ -500,47 +500,169 @@ dump_Elf_pt_load(struct DumpInfo *info,
}
int
+get_elf64_ehdr(struct DumpInfo *info, Elf64_Ehdr *ehdr)
+{
+ const off_t failed = (off_t)-1;
+
+ if (lseek(info->fd_memory, 0, SEEK_SET) == failed) {
+ ERRMSG("Can't seek the dump memory(%s). %s\n",
+ info->name_memory, strerror(errno));
+ return FALSE;
+ }
+ if (read(info->fd_memory, ehdr, sizeof(Elf64_Ehdr))
+ != sizeof(Elf64_Ehdr)) {
+ ERRMSG("Can't read the dump memory(%s). %s\n",
+ info->name_memory, strerror(errno));
+ return FALSE;
+ }
+ if (ehdr->e_ident[EI_CLASS] != ELFCLASS64) {
+ ERRMSG("Can't get valid e_ident.\n");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+int
+get_elf64_phdr(struct DumpInfo *info, int num, Elf64_Phdr *phdr)
+{
+ off_t offset;
+ const off_t failed = (off_t)-1;
+
+ offset = sizeof(Elf64_Ehdr) + sizeof(Elf64_Phdr) * num;
+
+ if (lseek(info->fd_memory, offset, SEEK_SET) == failed) {
+ ERRMSG("Can't seek the dump memory(%s). %s\n",
+ info->name_memory, strerror(errno));
+ return FALSE;
+ }
+ if (read(info->fd_memory, phdr, sizeof(Elf64_Phdr))
+ != sizeof(Elf64_Phdr)) {
+ ERRMSG("Can't read the dump memory(%s). %s\n",
+ info->name_memory, strerror(errno));
+ return FALSE;
+ }
+ return TRUE;
+}
+
+int
+dump_Elf32_load(struct DumpInfo *info, Elf32_Phdr *prog, int num_load)
+{
+ struct pt_load_segment *pls;
+
+ if (prog->p_type != PT_LOAD) {
+ ERRMSG("%s isn't the dump memory.\n", info->name_memory);
+ return FALSE;
+ }
+
+ pls = &info->pt_load_segments[num_load];
+ pls->phys_start = prog->p_paddr;
+ pls->phys_end = pls->phys_start + prog->p_filesz;
+ pls->virt_start = prog->p_vaddr;
+ pls->virt_end = pls->virt_start + prog->p_filesz;
+ pls->file_offset = prog->p_offset;
+ return TRUE;
+}
+
+int
+get_elf32_ehdr(struct DumpInfo *info, Elf32_Ehdr *ehdr)
+{
+ const off_t failed = (off_t)-1;
+
+ if (lseek(info->fd_memory, 0, SEEK_SET) == failed) {
+ ERRMSG("Can't seek the dump memory(%s). %s\n",
+ info->name_memory, strerror(errno));
+ return FALSE;
+ }
+ if (read(info->fd_memory, ehdr, sizeof(Elf32_Ehdr))
+ != sizeof(Elf32_Ehdr)) {
+ ERRMSG("Can't read the dump memory(%s). %s\n",
+ info->name_memory, strerror(errno));
+ return FALSE;
+ }
+ if (ehdr->e_ident[EI_CLASS] != ELFCLASS32) {
+ ERRMSG("Can't get valid e_ident.\n");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+int
+get_elf32_phdr(struct DumpInfo *info, int num, Elf32_Phdr *phdr)
+{
+ off_t offset;
+ const off_t failed = (off_t)-1;
+
+ offset = sizeof(Elf32_Ehdr) + sizeof(Elf32_Phdr) * num;
+
+ if (lseek(info->fd_memory, offset, SEEK_SET) == failed) {
+ ERRMSG("Can't seek the dump memory(%s). %s\n",
+ info->name_memory, strerror(errno));
+ return FALSE;
+ }
+ if (read(info->fd_memory, phdr, sizeof(Elf32_Phdr))
+ != sizeof(Elf32_Phdr)) {
+ ERRMSG("Can't read the dump memory(%s). %s\n",
+ info->name_memory, strerror(errno));
+ return FALSE;
+ }
+ return TRUE;
+}
+
+int
get_elf_info(struct DumpInfo *info)
{
int i, j;
unsigned long tmp;
- Elf *elfd = NULL;
- GElf_Ehdr ehdr;
- GElf_Phdr load;
+ Elf64_Ehdr ehdr64;
+ Elf64_Phdr load64;
+ Elf32_Ehdr ehdr32;
+ Elf32_Phdr load32;
const off_t failed = (off_t)-1;
int ret = FALSE;
+ /*
+ * Check ELF64 or ELF32.
+ */
if (lseek(info->fd_memory, 0, SEEK_SET) == failed) {
ERRMSG("Can't seek the dump memory(%s). %s\n",
info->name_memory, strerror(errno));
- return FALSE;
+ goto out;
}
- if (!(elfd = elf_begin(info->fd_memory, ELF_C_READ, NULL))) {
- ERRMSG("Can't get first elf header of %s.\n",
- info->name_memory);
+ if (read(info->fd_memory, &ehdr64, sizeof(Elf64_Ehdr))
+ != sizeof(Elf64_Ehdr)) {
+ ERRMSG("Can't read the dump memory(%s). %s\n",
+ info->name_memory, strerror(errno));
goto out;
}
- if (gelf_getehdr(elfd, &ehdr) == NULL) {
- ERRMSG("Can't find file header of %s.\n",
- info->name_memory);
+ if (lseek(info->fd_memory, 0, SEEK_SET) == failed) {
+ ERRMSG("Can't seek the dump memory(%s). %s\n",
+ info->name_memory, strerror(errno));
goto out;
}
-
- /*
- * get the ident string
- */
- if (ehdr.e_ident[EI_CLASS] == ELFCLASSNONE) {
- ERRMSG("Elf File has no class.\n");
+ if (read(info->fd_memory, &ehdr32, sizeof(Elf32_Ehdr))
+ != sizeof(Elf32_Ehdr)) {
+ ERRMSG("Can't read the dump memory(%s). %s\n",
+ info->name_memory, strerror(errno));
+ goto out;
+ }
+ if ((ehdr64.e_ident[EI_CLASS] == ELFCLASS64)
+ && (ehdr32.e_ident[EI_CLASS] != ELFCLASS32)) {
+ info->flag_elf64 = TRUE;
+ info->num_load_memory = ehdr64.e_phnum - 1;
+ } else if ((ehdr64.e_ident[EI_CLASS] != ELFCLASS64)
+ && (ehdr32.e_ident[EI_CLASS] == ELFCLASS32)) {
+ info->flag_elf64 = FALSE;
+ info->num_load_memory = ehdr32.e_phnum - 1;
+ } else {
+ ERRMSG("Can't get valid ehdr.\n");
goto out;
}
- info->num_load_memory = ehdr.e_phnum - 1;
if (!info->num_load_memory) {
ERRMSG("Can't get the number of PT_LOAD.\n");
goto out;
}
-
if ((info->pt_load_segments = (struct pt_load_segment *)
calloc(1, sizeof(struct pt_load_segment) *
info->num_load_memory)) == NULL) {
@@ -548,16 +670,39 @@ get_elf_info(struct DumpInfo *info)
strerror(errno));
goto out;
}
+ if (info->flag_elf64) { /* ELF64 */
+ for (i = 0, j = 0; i < ehdr64.e_phnum; i++) {
+ if (!get_elf64_phdr(info, i, &load64)) {
+ ERRMSG("Can't find Phdr %d.\n", i);
+ goto out;
+ }
+ if (load64.p_type != PT_LOAD)
+ continue;
- for (i = 0, j = 0; i < ehdr.e_phnum; i++) {
- if (gelf_getphdr(elfd, i, &load) == NULL) {
- ERRMSG("Can't find Phdr %d.\n", i);
- goto out;
+ if (j == 0) {
+ info->offset_load_memory = load64.p_offset;
+ if (!info->offset_load_memory) {
+ ERRMSG("Can't get the offset of page
data.\n");
+ goto out;
+ }
+ }
+ if (j >= info->num_load_memory)
+ goto out;
+ if(!dump_Elf64_load(info, &load64, j))
+ goto out;
+ j++;
}
+ } else { /* ELF32 */
+ for (i = 0, j = 0; i < ehdr32.e_phnum; i++) {
+ if (!get_elf32_phdr(info, i, &load32)) {
+ ERRMSG("Can't find Phdr %d.\n", i);
+ goto out;
+ }
+ if (load32.p_type != PT_LOAD)
+ continue;
- if (load.p_type == PT_LOAD) {
if (j == 0) {
- info->offset_load_memory = load.p_offset;
+ info->offset_load_memory = load32.p_offset;
if (!info->offset_load_memory) {
ERRMSG("Can't get the offset of page
data.\n");
goto out;
@@ -565,8 +710,7 @@ get_elf_info(struct DumpInfo *info)
}
if (j >= info->num_load_memory)
goto out;
-
- if(!dump_Elf_pt_load(info, &load, j))
+ if(!dump_Elf32_load(info, &load32, j))
goto out;
j++;
}
@@ -587,9 +731,6 @@ get_elf_info(struct DumpInfo *info)
ret = TRUE;
out:
- if (elfd != NULL)
- elf_end(elfd);
-
return ret;
}
@@ -2220,14 +2361,15 @@ out:
int
get_loads_dumpfile(struct DumpInfo *info)
{
- int i, num_new_load = 0;
+ int i, phnum, num_new_load = 0;
+ long page_size = info->page_size;
unsigned long long pfn, pfn_start, pfn_end, num_excluded;
unsigned long frac_head, frac_tail;
- Elf *elfd = NULL;
- GElf_Ehdr ehdr;
- GElf_Phdr load;
+ Elf64_Ehdr ehdr64;
+ Elf64_Phdr load64;
+ Elf32_Ehdr ehdr32;
+ Elf32_Phdr load32;
struct dump_bitmap bitmap2;
- const off_t failed = (off_t)-1;
bitmap2.fd = info->fd_bitmap;
bitmap2.file_name = info->name_bitmap;
@@ -2240,37 +2382,47 @@ get_loads_dumpfile(struct DumpInfo *info
strerror(errno));
goto out;
}
- if (lseek(info->fd_memory, 0, SEEK_SET) == failed) {
- ERRMSG("Can't seek the dump memory(%s). %s\n",
- info->name_memory, strerror(errno));
- goto out;
- }
- if (!(elfd = elf_begin(info->fd_memory, ELF_C_READ, NULL))) {
- ERRMSG("Can't get first elf header of %s.\n",
- info->name_memory);
- goto out;
- }
- if (gelf_getehdr(elfd, &ehdr) == NULL) {
- ERRMSG("Can't find file header of %s.\n",
- info->name_memory);
- goto out;
- }
- for (i = 0; i < ehdr.e_phnum; i++) {
- if (gelf_getphdr(elfd, i, &load) == NULL) {
- ERRMSG("Can't find Phdr %d.\n", i);
+ if (info->flag_elf64) { /* ELF64 */
+ if (!get_elf64_ehdr(info, &ehdr64)) {
+ ERRMSG("Can't get ehdr64.\n");
goto out;
}
- if (load.p_type != PT_LOAD)
- continue;
-
- num_excluded = 0;
+ phnum = ehdr64.e_phnum;
+ } else { /* ELF32 */
+ if (!get_elf32_ehdr(info, &ehdr32)) {
+ ERRMSG("Can't get ehdr32.\n");
+ goto out;
+ }
+ phnum = ehdr32.e_phnum;
+ }
+ for (i = 0; i < phnum; i++) {
+ if (info->flag_elf64) { /* ELF64 */
+ if (!get_elf64_phdr(info, i, &load64)) {
+ ERRMSG("Can't find Phdr %d.\n", i);
+ goto out;
+ }
+ if (load64.p_type != PT_LOAD)
+ continue;
+ pfn_start = load64.p_paddr / page_size;
+ pfn_end = (load64.p_paddr+load64.p_memsz)/page_size;
+ frac_head = page_size - (load64.p_paddr % page_size);
+ frac_tail = (load64.p_paddr+load64.p_memsz)%page_size;
+ } else { /* ELF32 */
+ if (!get_elf32_phdr(info, i, &load32)) {
+ ERRMSG("Can't find Phdr %d.\n", i);
+ goto out;
+ }
+ if (load32.p_type != PT_LOAD)
+ continue;
+ pfn_start = load32.p_paddr / page_size;
+ pfn_end = (load32.p_paddr+load32.p_memsz)/page_size;
+ frac_head = page_size - (load32.p_paddr % page_size);
+ frac_tail = (load32.p_paddr+load32.p_memsz)%page_size;
+ }
num_new_load++;
- pfn_start = load.p_paddr / info->page_size;
- pfn_end = (load.p_paddr + load.p_memsz) / info->page_size;
- frac_head = info->page_size - (load.p_paddr % info->page_size);
- frac_tail = (load.p_paddr + load.p_memsz) % info->page_size;
+ num_excluded = 0;
- if (frac_head && (frac_head != info->page_size))
+ if (frac_head && (frac_head != page_size))
pfn_start++;
if (frac_tail)
pfn_end++;
@@ -2295,8 +2447,6 @@ get_loads_dumpfile(struct DumpInfo *info
out:
if (bitmap2.buf != NULL)
free(bitmap2.buf);
- if (elfd != NULL)
- elf_end(elfd);
return num_new_load;
}
@@ -2304,10 +2454,12 @@ int
write_elf_header(struct DumpInfo *info)
{
int i, num_loads_dumpfile;
- off_t offset_note_memory;
- Elf *elfd = NULL;
- GElf_Ehdr ehdr;
- GElf_Phdr note;
+ off_t offset_note_memory, offset_note_dumpfile;
+ size_t size_note;
+ Elf64_Ehdr ehdr64;
+ Elf64_Phdr note64;
+ Elf32_Ehdr ehdr32;
+ Elf32_Phdr note32;
char *buf = NULL;
const off_t failed = (off_t)-1;
@@ -2325,25 +2477,25 @@ write_elf_header(struct DumpInfo *info)
goto out;
}
- if (lseek(info->fd_memory, 0, SEEK_SET) == failed) {
- ERRMSG("Can't seek the dump memory(%s). %s\n",
- info->name_memory, strerror(errno));
- goto out;
- }
- if (!(elfd = elf_begin(info->fd_memory, ELF_C_READ, NULL))) {
- ERRMSG("Can't get first elf header of %s.\n",
- info->name_memory);
- goto out;
- }
- if (gelf_getehdr(elfd, &ehdr) == NULL) {
- ERRMSG("Can't find file header of %s.\n",
- info->name_memory);
- goto out;
+ if (info->flag_elf64) { /* ELF64 */
+ if (!get_elf64_ehdr(info, &ehdr64)) {
+ ERRMSG("Can't get ehdr64.\n");
+ goto out;
+ }
+ /*
+ * PT_NOTE(1) + PT_LOAD(1+)
+ */
+ ehdr64.e_phnum = 1 + num_loads_dumpfile;
+ } else { /* ELF32 */
+ if (!get_elf32_ehdr(info, &ehdr32)) {
+ ERRMSG("Can't get ehdr32.\n");
+ goto out;
+ }
+ /*
+ * PT_NOTE(1) + PT_LOAD(1+)
+ */
+ ehdr32.e_phnum = 1 + num_loads_dumpfile;
}
- /*
- * PT_NOTE(1) + PT_LOAD(1+)
- */
- ehdr.e_phnum = 1 + num_loads_dumpfile;
/*
* Write a ELF header.
@@ -2353,38 +2505,84 @@ write_elf_header(struct DumpInfo *info)
info->name_dumpfile, strerror(errno));
goto out;
}
- if (write(info->fd_dumpfile, &ehdr, sizeof(ehdr)) != sizeof(ehdr)) {
- ERRMSG("Can't write the dump file(%s). %s\n",
- info->name_dumpfile, strerror(errno));
- goto out;
+ if (info->flag_elf64) { /* ELF64 */
+ if (write(info->fd_dumpfile, &ehdr64, sizeof(ehdr64))
+ != sizeof(ehdr64)) {
+ ERRMSG("Can't write the dump file(%s). %s\n",
+ info->name_dumpfile, strerror(errno));
+ goto out;
+ }
+ } else { /* ELF32 */
+ if (write(info->fd_dumpfile, &ehdr32, sizeof(ehdr32))
+ != sizeof(ehdr32)) {
+ ERRMSG("Can't write the dump file(%s). %s\n",
+ info->name_dumpfile, strerror(errno));
+ goto out;
+ }
}
+
/*
* Write a PT_NOTE header.
*/
- for (i = 0; i < ehdr.e_phnum; i++) {
- if (gelf_getphdr(elfd, i, ¬e) == NULL) {
- ERRMSG("Can't find Phdr %d.\n", i);
+ if (info->flag_elf64) { /* ELF64 */
+ for (i = 0; i < ehdr64.e_phnum; i++) {
+ if (!get_elf64_phdr(info, i, ¬e64)) {
+ ERRMSG("Can't find Phdr %d.\n", i);
+ goto out;
+ }
+ if (note64.p_type == PT_NOTE)
+ break;
+ }
+ if (note64.p_type != PT_NOTE) {
+ ERRMSG("Can't get a PT_NOTE header.\n");
+ goto out;
+ }
+
+ offset_note_memory = note64.p_offset;
+ offset_note_dumpfile = sizeof(ehdr64)
+ + sizeof(Elf64_Phdr) * ehdr64.e_phnum;
+ note64.p_offset = offset_note_dumpfile;
+ size_note = note64.p_filesz;
+
+ if (write(info->fd_dumpfile, ¬e64, sizeof(note64))
+ != sizeof(note64)) {
+ ERRMSG("Can't write the dump file(%s). %s\n",
+ info->name_dumpfile, strerror(errno));
+ goto out;
+ }
+ } else { /* ELF32 */
+ for (i = 0; i < ehdr32.e_phnum; i++) {
+ if (!get_elf32_phdr(info, i, ¬e32)) {
+ ERRMSG("Can't find Phdr %d.\n", i);
+ goto out;
+ }
+ if (note32.p_type == PT_NOTE)
+ break;
+ }
+ if (note32.p_type != PT_NOTE) {
+ ERRMSG("Can't get a PT_NOTE header.\n");
+ goto out;
+ }
+
+ offset_note_memory = note32.p_offset;
+ offset_note_dumpfile = sizeof(ehdr32)
+ + sizeof(Elf32_Phdr) * ehdr32.e_phnum;
+ note32.p_offset = offset_note_dumpfile;
+ size_note = note32.p_filesz;
+
+ if (write(info->fd_dumpfile, ¬e32, sizeof(note32))
+ != sizeof(note32)) {
+ ERRMSG("Can't write the dump file(%s). %s\n",
+ info->name_dumpfile, strerror(errno));
goto out;
}
- if (note.p_type == PT_NOTE)
- break;
- }
- if (note.p_type != PT_NOTE) {
- ERRMSG("Can't get a PT_NOTE header.\n");
- goto out;
- }
- offset_note_memory = note.p_offset;
- note.p_offset = sizeof(ehdr) + sizeof(GElf_Phdr)*ehdr.e_phnum;
- if (write(info->fd_dumpfile, ¬e, sizeof(note)) != sizeof(note)) {
- ERRMSG("Can't write the dump file(%s). %s\n",
- info->name_dumpfile, strerror(errno));
- goto out;
}
+
/*
* Write a PT_NOTE segment.
* PT_LOAD header will be written later.
*/
- if ((buf = malloc(note.p_filesz)) == NULL) {
+ if ((buf = malloc(size_note)) == NULL) {
ERRMSG("Can't allocate memory for PT_NOTE segment. %s\n",
strerror(errno));
goto out;
@@ -2394,16 +2592,16 @@ write_elf_header(struct DumpInfo *info)
info->name_memory, strerror(errno));
goto out;
}
- if (read(info->fd_memory, buf, note.p_filesz) != note.p_filesz) {
+ if (read(info->fd_memory, buf, size_note) != size_note) {
ERRMSG("Can't read the dump memory(%s). %s\n",
info->name_memory, strerror(errno));
goto out;
}
- if (lseek(info->fd_dumpfile, note.p_offset, SEEK_SET) == failed) {
+ if (lseek(info->fd_dumpfile, offset_note_dumpfile, SEEK_SET) == failed){
ERRMSG("Can't seek the dump file(%s). %s\n",
info->name_dumpfile, strerror(errno));
}
- if (write(info->fd_dumpfile, buf, note.p_filesz) != note.p_filesz) {
+ if (write(info->fd_dumpfile, buf, size_note) != size_note) {
ERRMSG("Can't write the dump file(%s). %s\n",
info->name_dumpfile, strerror(errno));
goto out;
@@ -2412,7 +2610,7 @@ write_elf_header(struct DumpInfo *info)
/*
* Set a offset of PT_LOAD segment.
*/
- info->offset_load_dumpfile = note.p_offset + note.p_filesz;
+ info->offset_load_dumpfile = offset_note_dumpfile + size_note;
ret = TRUE;
out:
@@ -2501,16 +2699,18 @@ print_progress(unsigned long current, un
int
write_elf_pages(struct DumpInfo *info)
{
- int i;
+ int i, phnum;
+ long page_size = info->page_size;
long long bufsz_write, bufsz_remain;
- unsigned long long pfn, pfn_start, pfn_end, num_excluded;
+ unsigned long long pfn, pfn_start, pfn_end, paddr, num_excluded;
unsigned long long num_dumpable = 0, num_dumped = 0, per;
unsigned long long memsz, filesz;
unsigned long frac_head, frac_tail;
off_t off_hdr_load, off_seg_load, off_memory;
- Elf *elfd = NULL;
- GElf_Ehdr ehdr;
- GElf_Phdr load;
+ Elf64_Ehdr ehdr64;
+ Elf64_Phdr load64;
+ Elf32_Ehdr ehdr32;
+ Elf32_Phdr load32;
char *buf = NULL;
struct dump_bitmap bitmap2;
const off_t failed = (off_t)-1;
@@ -2545,41 +2745,56 @@ write_elf_pages(struct DumpInfo *info)
per = num_dumpable / 100;
off_seg_load = info->offset_load_dumpfile;
- off_hdr_load = sizeof(GElf_Ehdr) + sizeof(GElf_Phdr);
off_memory = 0;
- if (lseek(info->fd_memory, 0, SEEK_SET) == failed) {
- ERRMSG("Can't seek the dump memory(%s). %s\n",
- info->name_memory, strerror(errno));
- goto out;
- }
- if (!(elfd = elf_begin(info->fd_memory, ELF_C_READ, NULL))) {
- ERRMSG("Can't get first elf header of %s.\n",
- info->name_memory);
- goto out;
- }
- if (gelf_getehdr(elfd, &ehdr) == NULL) {
- ERRMSG("Can't find file header of %s.\n",
- info->name_memory);
- goto out;
- }
- for (i = 0; i < ehdr.e_phnum; i++) {
- if (gelf_getphdr(elfd, i, &load) == NULL) {
- ERRMSG("Can't find Phdr %d.\n", i);
+ if (info->flag_elf64) { /* ELF64 */
+ off_hdr_load = sizeof(Elf64_Ehdr) + sizeof(Elf64_Phdr);
+ if (!get_elf64_ehdr(info, &ehdr64)) {
+ ERRMSG("Can't get ehdr64.\n");
goto out;
}
- if (load.p_type != PT_LOAD)
- continue;
+ phnum = ehdr64.e_phnum;
+ } else { /* ELF32 */
+ off_hdr_load = sizeof(Elf32_Ehdr) + sizeof(Elf32_Phdr);
+ if (!get_elf32_ehdr(info, &ehdr32)) {
+ ERRMSG("Can't get ehdr32.\n");
+ goto out;
+ }
+ phnum = ehdr32.e_phnum;
+ }
+
+ for (i = 0; i < phnum; i++) {
+ if (info->flag_elf64) { /* ELF64 */
+ if (!get_elf64_phdr(info, i, &load64)) {
+ ERRMSG("Can't find Phdr %d.\n", i);
+ goto out;
+ }
+ if (load64.p_type != PT_LOAD)
+ continue;
+
+ paddr = load64.p_paddr;
+ pfn_start = load64.p_paddr / page_size;
+ pfn_end = (load64.p_paddr+ load64.p_memsz)/page_size;
+ frac_head = page_size - (load64.p_paddr % page_size);
+ frac_tail = (load64.p_paddr+ load64.p_memsz)%page_size;
+ } else { /* ELF32 */
+ if (!get_elf32_phdr(info, i, &load32)) {
+ ERRMSG("Can't find Phdr %d.\n", i);
+ goto out;
+ }
+ if (load32.p_type != PT_LOAD)
+ continue;
+ paddr = load32.p_paddr;
+ pfn_start = load32.p_paddr / page_size;
+ pfn_end = (load32.p_paddr+ load32.p_memsz)/page_size;
+ frac_head = page_size - (load32.p_paddr % page_size);
+ frac_tail = (load32.p_paddr+ load32.p_memsz)%page_size;
+ }
num_excluded = 0;
memsz = 0;
filesz = 0;
- pfn_start = load.p_paddr / info->page_size;
- pfn_end = (load.p_paddr + load.p_memsz) / info->page_size;
- frac_head = info->page_size - (load.p_paddr % info->page_size);
- frac_tail = (load.p_paddr + load.p_memsz) % info->page_size;
-
- if (frac_head && (frac_head != info->page_size)) {
+ if (frac_head && (frac_head != page_size)) {
memsz = frac_head;
filesz = frac_head;
pfn_start++;
@@ -2593,7 +2808,7 @@ write_elf_pages(struct DumpInfo *info)
if ((pfn == pfn_end - 1) && frac_tail)
memsz += frac_tail;
else
- memsz += info->page_size;
+ memsz += page_size;
continue;
}
@@ -2605,8 +2820,8 @@ write_elf_pages(struct DumpInfo *info)
memsz += frac_tail;
filesz += frac_tail;
} else {
- memsz += info->page_size;
- filesz += info->page_size;
+ memsz += page_size;
+ filesz += page_size;
}
continue;
/*
@@ -2616,12 +2831,12 @@ write_elf_pages(struct DumpInfo *info)
} else if (num_excluded < PFN_EXCLUDED) {
if ((pfn == pfn_end - 1) && frac_tail) {
memsz += frac_tail;
- filesz += (info->page_size*num_excluded
+ filesz += (page_size*num_excluded
+ frac_tail);
}else {
- memsz += info->page_size;
- filesz += (info->page_size*num_excluded
- + info->page_size);
+ memsz += page_size;
+ filesz += (page_size*num_excluded
+ + page_size);
}
num_excluded = 0;
continue;
@@ -2632,9 +2847,15 @@ write_elf_pages(struct DumpInfo *info)
* is 256 or more, those pages are excluded really.
* And a new PT_LOAD segment is created.
*/
- load.p_memsz = memsz;
- load.p_filesz = filesz;
- load.p_offset = off_seg_load;
+ if (info->flag_elf64) { /* ELF64 */
+ load64.p_memsz = memsz;
+ load64.p_filesz = filesz;
+ load64.p_offset = off_seg_load;
+ } else { /* ELF32 */
+ load32.p_memsz = memsz;
+ load32.p_filesz = filesz;
+ load32.p_offset = off_seg_load;
+ }
/*
* Write a PT_LOAD header.
@@ -2645,19 +2866,28 @@ write_elf_pages(struct DumpInfo *info)
info->name_dumpfile, strerror(errno));
goto out;
}
- if (write(info->fd_dumpfile, &load, sizeof(load))
- != sizeof(load)) {
- ERRMSG("Can't write the dump file(%s). %s\n",
- info->name_dumpfile, strerror(errno));
- goto out;
+ if (info->flag_elf64) { /* ELF64 */
+ if (write(info->fd_dumpfile, &load64,
+ sizeof(load64)) != sizeof(load64)) {
+ ERRMSG("Can't write the dump file(%s).
%s\n",
+ info->name_dumpfile,
strerror(errno));
+ goto out;
+ }
+ } else { /* ELF32 */
+ if (write(info->fd_dumpfile, &load32,
+ sizeof(load32)) != sizeof(load32)) {
+ ERRMSG("Can't write the dump file(%s).
%s\n",
+ info->name_dumpfile,
strerror(errno));
+ goto out;
+ }
}
/*
* Write a PT_LOAD segment.
*/
- off_memory = paddr_to_offset(info, load.p_paddr);
+ off_memory = paddr_to_offset(info, paddr);
if (!off_memory) {
- ERRMSG("Can't convert physaddr(%lx) to a
offset.\n",
- (unsigned long)load.p_paddr);
+ ERRMSG("Can't convert physaddr(%llx) to a
offset.\n",
+ paddr);
goto out;
}
if (lseek(info->fd_memory, off_memory, SEEK_SET)
@@ -2673,13 +2903,17 @@ write_elf_pages(struct DumpInfo *info)
goto out;
}
- bufsz_remain = load.p_filesz;
+ if (info->flag_elf64) /* ELF64 */
+ bufsz_remain = load64.p_filesz;
+ else /* ELF32 */
+ bufsz_remain = load32.p_filesz;
+
while (bufsz_remain > 0) {
if ((num_dumped % per) == 0)
print_progress(num_dumped,
num_dumpable);
- if (bufsz_remain >= info->page_size)
- bufsz_write = info->page_size;
+ if (bufsz_remain >= page_size)
+ bufsz_write = page_size;
else
bufsz_write = bufsz_remain;
@@ -2695,24 +2929,48 @@ write_elf_pages(struct DumpInfo *info)
info->name_dumpfile,
strerror(errno));
goto out;
}
- bufsz_remain -= info->page_size;
+ bufsz_remain -= page_size;
num_dumped++;
}
- load.p_paddr += load.p_memsz;
- if (load.p_paddr < MAXMEM)
- load.p_vaddr += load.p_memsz;
- memsz = info->page_size;
- filesz = info->page_size;
- off_hdr_load += sizeof(load);
- off_seg_load += load.p_filesz;
+ if (info->flag_elf64) { /* ELF64 */
+ load64.p_paddr += load64.p_memsz;
+#ifdef __x86__
+ if (load64.p_paddr < MAXMEM)
+ load64.p_vaddr += load64.p_memsz;
+#else
+ load64.p_vaddr += load64.p_memsz;
+#endif /* x86 */
+ paddr = load64.p_paddr;
+ off_hdr_load += sizeof(load64);
+ off_seg_load += load64.p_filesz;
+ } else { /* ELF32 */
+ load32.p_paddr += load32.p_memsz;
+#ifdef __x86__
+ if (load32.p_paddr < MAXMEM)
+ load32.p_vaddr += load32.p_memsz;
+#else
+ load32.p_vaddr += load32.p_memsz;
+#endif /* x86 */
+ paddr = load32.p_paddr;
+ off_hdr_load += sizeof(load32);
+ off_seg_load += load32.p_filesz;
+ }
num_excluded = 0;
+ memsz = page_size;
+ filesz = page_size;
}
/*
* Write the last PT_LOAD.
*/
- load.p_memsz = memsz;
- load.p_filesz = filesz;
- load.p_offset = off_seg_load;
+ if (info->flag_elf64) { /* ELF64 */
+ load64.p_memsz = memsz;
+ load64.p_filesz = filesz;
+ load64.p_offset = off_seg_load;
+ } else { /* ELF32 */
+ load32.p_memsz = memsz;
+ load32.p_filesz = filesz;
+ load32.p_offset = off_seg_load;
+ }
/*
* Write a PT_LOAD header.
@@ -2723,19 +2981,29 @@ write_elf_pages(struct DumpInfo *info)
info->name_dumpfile, strerror(errno));
goto out;
}
- if (write(info->fd_dumpfile, &load, sizeof(load))
- != sizeof(load)) {
- ERRMSG("Can't write the dump file(%s). %s\n",
- info->name_dumpfile, strerror(errno));
- goto out;
+ if (info->flag_elf64) { /* ELF64 */
+ if (write(info->fd_dumpfile, &load64, sizeof(load64))
+ != sizeof(load64)) {
+ ERRMSG("Can't write the dump file(%s). %s\n",
+ info->name_dumpfile, strerror(errno));
+ goto out;
+ }
+ } else { /* ELF32 */
+ if (write(info->fd_dumpfile, &load32, sizeof(load32))
+ != sizeof(load32)) {
+ ERRMSG("Can't write the dump file(%s). %s\n",
+ info->name_dumpfile, strerror(errno));
+ goto out;
+ }
}
+
/*
* Write a PT_LOAD segment.
*/
- off_memory = paddr_to_offset(info, load.p_paddr);
+ off_memory = paddr_to_offset(info, paddr);
if (!off_memory) {
- ERRMSG("Can't convert physaddr(%lx) to a offset.\n",
- (unsigned long)load.p_paddr);
+ ERRMSG("Can't convert physaddr(%llx) to a offset.\n",
+ paddr);
goto out;
}
if (lseek(info->fd_memory, off_memory, SEEK_SET)
@@ -2750,13 +3018,17 @@ write_elf_pages(struct DumpInfo *info)
info->name_dumpfile, strerror(errno));
goto out;
}
- bufsz_remain = load.p_filesz;
+ if (info->flag_elf64) /* ELF64 */
+ bufsz_remain = load64.p_filesz;
+ else /* ELF32 */
+ bufsz_remain = load32.p_filesz;
+
while (bufsz_remain > 0) {
if ((num_dumped % per) == 0)
print_progress(num_dumped, num_dumpable);
- if (bufsz_remain >= info->page_size)
- bufsz_write = info->page_size;
+ if (bufsz_remain >= page_size)
+ bufsz_write = page_size;
else
bufsz_write = bufsz_remain;
@@ -2772,11 +3044,16 @@ write_elf_pages(struct DumpInfo *info)
info->name_dumpfile, strerror(errno));
goto out;
}
- bufsz_remain -= info->page_size;
+ bufsz_remain -= page_size;
num_dumped++;
}
- off_hdr_load += sizeof(load);
- off_seg_load += load.p_filesz;
+ if (info->flag_elf64) { /* ELF64 */
+ off_hdr_load += sizeof(load64);
+ off_seg_load += load64.p_filesz;
+ } else { /* ELF32 */
+ off_hdr_load += sizeof(load32);
+ off_seg_load += load32.p_filesz;
+ }
}
print_progress(num_dumpable, num_dumpable);
ret = TRUE;
@@ -2785,8 +3062,6 @@ out:
free(buf);
if (bitmap2.buf != NULL)
free(bitmap2.buf);
- if (elfd != NULL)
- elf_end(elfd);
return ret;
}
diff -puN backup/v1.0.6/makedumpfile.h makedumpfile/makedumpfile.h
--- backup/v1.0.6/makedumpfile.h 2006-11-27 15:50:15.000000000 +0900
+++ makedumpfile/makedumpfile.h 2006-12-04 21:33:14.000000000 +0900
@@ -288,7 +288,6 @@ do { \
#define VMALLOC_END (0xffffe1ffffffffff)
#define MODULES_VADDR (0xffffffff88000000)
#define MODULES_END (0xfffffffffff00000)
-#define MAXMEM (0x3fffffffffffUL)
#define KVBASE PAGE_OFFSET
#define _SECTION_SIZE_BITS (27)
#define SIZEOF_NODE_ONLINE_MAP (8)
@@ -299,7 +298,6 @@ do { \
#define PAGE_OFFSET (0xc000000000000000)
#define KERNELBASE PAGE_OFFSET
#define VMALLOCBASE (0xD000000000000000)
-#define MAXMEM (-KERNELBASE-VMALLOCBASE)
#define KVBASE (SYMBOL(_stext))
#define _SECTION_SIZE_BITS (24)
#define SIZEOF_NODE_ONLINE_MAP (8)
@@ -307,7 +305,6 @@ do { \
#endif
#ifdef __ia64__ /* ia64 */
-#define MAXMEM (0xffffffffffffffff)
#define REGION_SHIFT (61)
#define KERNEL_CACHED_REGION (7)
@@ -410,7 +407,8 @@ struct DumpInfo {
*/
int dump_level; /* dump level */
int flag_compress; /* flag of compression */
- int flag_elf_dumpfile; /* flag of elf dump file */
+ int flag_elf64; /* flag of ELF64 memory */
+ int flag_elf_dumpfile; /* flag of creating ELF dumpfile */
int flag_vmlinux; /* flag of vmlinux */
int flag_generate_config;/* flag of generating config file
*/
int flag_read_config; /* flag of reading config file */
_______________________________________________
fastboot mailing list
[email protected]
https://lists.osdl.org/mailman/listinfo/fastboot