[PATCH] [makedumpfile] Fix ELF output with overlapping sections
Ken'ichi Ohmichi
oomichi at mxs.nes.nec.co.jp
Wed May 30 22:26:08 EDT 2007
Hi Bernhard,
2007/05/18 12:47:15 +0200, Bernhard Walle <bwalle at suse.de> wrote:
>I have a core dump with following program headers on IA64:
>
> LOAD 0x0000000000001f4c 0xa000000100000000 0x0000000004000000
> 0x000000000055c4a0 0x000000000055c4a0 RWE 0
>...
> LOAD 0x00000000044fc3ec 0xe000000004000000 0x0000000004000000
> 0x0000000000c92000 0x0000000000c92000 RWE 0
>
>The interesting thing is the overlap in the physical address space.
>write_elf_pages() assumes that there's no overlap because it looks only
>for the file offset according to the physical start address and silently
>assumes that the length matches.
Thank you for the patch.
I'm worry that the overlapping spaces may have the same p_filesz.
I think it is certain to check it by p_offset, and created the
attached patch. Please let me know your opinion.
BTW, I don't know the reason why your system's /proc/vmcore has the
overlapping physical address. If you know it, please let me know.
Thanks
Ken'ichi Ohmichi
------------------------------------------------------------
Signed-off-by: Bernhard Walle <bwalle at suse.de>
Signed-off-by: Ken'ichi Ohmichi <oomichi at mxs.nes.nec.co.jp>
---
diff -puN backup/v1.1.3/makedumpfile.c a/makedumpfile.c
--- backup/v1.1.3/makedumpfile.c 2007-04-13 15:44:55.000000000 +0900
+++ a/makedumpfile.c 2007-05-31 11:18:04.000000000 +0900
@@ -2561,6 +2561,33 @@ out:
return ret;
}
+/*
+ * Sames as paddr_to_offset() but makes sure that the specified offset (hint)
+ * in the segment.
+ */
+off_t
+paddr_to_offset2(struct DumpInfo *info, unsigned long long paddr, off_t hint)
+{
+ int i;
+ off_t offset;
+ unsigned long long len;
+ struct pt_load_segment *pls;
+
+ for (i = offset = 0; i < info->num_load_memory; i++) {
+ pls = &info->pt_load_segments[i];
+ len = pls->phys_end - pls->phys_start;
+ if ((paddr >= pls->phys_start)
+ && (paddr < pls->phys_end)
+ && (hint >= pls->file_offset)
+ && (hint < pls->file_offset + len)) {
+ offset = (off_t)(paddr - pls->phys_start) +
+ pls->file_offset;
+ break;
+ }
+ }
+ return offset;
+}
+
unsigned long long
page_to_pfn(struct DumpInfo *info, unsigned long page)
{
@@ -3462,7 +3489,6 @@ write_elf_pages(struct DumpInfo *info)
off_seg_load = info->offset_load_dumpfile;
cd_seg.offset = info->offset_load_dumpfile;
- off_memory = 0;
if (info->flag_elf64) { /* ELF64 */
cd_hdr.offset = sizeof(Elf64_Ehdr) + sizeof(Elf64_Phdr);
@@ -3488,7 +3514,7 @@ write_elf_pages(struct DumpInfo *info)
}
if (load64.p_type != PT_LOAD)
continue;
-
+ off_memory= load64.p_offset;
paddr = load64.p_paddr;
pfn_start = load64.p_paddr / page_size;
pfn_end = (load64.p_paddr+ load64.p_memsz)/page_size;
@@ -3501,6 +3527,7 @@ write_elf_pages(struct DumpInfo *info)
}
if (load32.p_type != PT_LOAD)
continue;
+ off_memory= load32.p_offset;
paddr = load32.p_paddr;
pfn_start = load32.p_paddr / page_size;
pfn_end = (load32.p_paddr+ load32.p_memsz)/page_size;
@@ -3588,7 +3615,7 @@ write_elf_pages(struct DumpInfo *info)
/*
* Write a PT_LOAD segment.
*/
- off_memory = paddr_to_offset(info, paddr);
+ off_memory = paddr_to_offset2(info, paddr, off_memory);
if (!off_memory) {
ERRMSG("Can't convert physaddr(%llx) to a offset.\n",
paddr);
@@ -3680,7 +3707,7 @@ write_elf_pages(struct DumpInfo *info)
/*
* Write a PT_LOAD segment.
*/
- off_memory = paddr_to_offset(info, paddr);
+ off_memory = paddr_to_offset2(info, paddr, off_memory);
if (!off_memory) {
ERRMSG("Can't convert physaddr(%llx) to a offset.\n",
paddr);
_
More information about the kexec
mailing list