linux-2.6.33/elf_core_dump()
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
検索
|
最終更新
|
ヘルプ
|
ログイン
]
開始行:
*参照元 [#g685cf4a]
#backlinks
*説明 [#va855e73]
-パス: [[linux-2.6.33/fs/binfmt_elf.c]]
-FIXME: これは何?
--説明
**引数 [#i963e8b1]
-
--
**返り値 [#qf442fb6]
-
--
**参考 [#edf5e669]
*実装 [#qc5e91f9]
/*
* Actual dumper
*
* This is a two-pass process; first we find the offsets...
* and then they are actually written out. If we run ou...
* we just truncate.
*/
static int elf_core_dump(struct coredump_params *cprm)
{
int has_dumped = 0;
mm_segment_t fs;
int segs;
size_t size = 0;
struct vm_area_struct *vma, *gate_vma;
struct elfhdr *elf = NULL;
loff_t offset = 0, dataoff, foffset;
unsigned long mm_flags;
struct elf_note_info info;
/*
* We no longer stop all VM operations.
*
* This is because those proceses that could possibly c...
* or the mmap / vma pages are now blocked in do_exit o...
* finishing this core dump.
*
* Only ptrace can touch these memory addresses, but it...
* the map_count or the pages allocated. So no possibil...
* exists while dumping the mm->vm_next areas to the co...
*/
/* alloc memory for large data structures: too large to...
elf = kmalloc(sizeof(*elf), GFP_KERNEL);
if (!elf)
goto out;
/*
* The number of segs are recored into ELF header as 16...
* Please check DEFAULT_MAX_MAP_COUNT definition when y...
*/
segs = current->mm->map_count;
#ifdef ELF_CORE_EXTRA_PHDRS
segs += ELF_CORE_EXTRA_PHDRS;
#endif
gate_vma = get_gate_vma(current);
if (gate_vma != NULL)
segs++;
/*
* Collect all the non-memory information about the pro...
* notes. This also sets up the file header.
*/
if (!fill_note_info(elf, segs + 1, /* including notes s...
&info, cprm->signr, cprm->regs))
goto cleanup;
has_dumped = 1;
current->flags |= PF_DUMPCORE;
fs = get_fs();
set_fs(KERNEL_DS);
DUMP_WRITE(elf, sizeof(*elf));
offset += sizeof(*elf); /* Elf header */
offset += (segs + 1) * sizeof(struct elf_phdr); /* Prog...
foffset = offset;
/* Write notes phdr entry */
{
struct elf_phdr phdr;
size_t sz = get_note_info_size(&info);
sz += elf_coredump_extra_notes_size();
fill_elf_note_phdr(&phdr, sz, offset);
offset += sz;
DUMP_WRITE(&phdr, sizeof(phdr));
}
dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE);
/*
* We must use the same mm->flags while dumping core to...
* inconsistency between the program headers and bodies...
* unusable core file can be generated.
*/
mm_flags = current->mm->flags;
/* Write program headers for segments dump */
for (vma = first_vma(current, gate_vma); vma != NULL;
vma = next_vma(vma, gate_vma)) {
struct elf_phdr phdr;
phdr.p_type = PT_LOAD;
phdr.p_offset = offset;
phdr.p_vaddr = vma->vm_start;
phdr.p_paddr = 0;
phdr.p_filesz = vma_dump_size(vma, mm_flags);
phdr.p_memsz = vma->vm_end - vma->vm_start;
offset += phdr.p_filesz;
phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
if (vma->vm_flags & VM_WRITE)
phdr.p_flags |= PF_W;
if (vma->vm_flags & VM_EXEC)
phdr.p_flags |= PF_X;
phdr.p_align = ELF_EXEC_PAGESIZE;
DUMP_WRITE(&phdr, sizeof(phdr));
}
#ifdef ELF_CORE_WRITE_EXTRA_PHDRS
ELF_CORE_WRITE_EXTRA_PHDRS;
#endif
/* write out the notes section */
if (!write_note_info(&info, cprm->file, &foffset))
goto end_coredump;
if (elf_coredump_extra_notes_write(cprm->file, &foffset))
goto end_coredump;
/* Align to page */
if (!dump_seek(cprm->file, dataoff - foffset))
goto end_coredump;
for (vma = first_vma(current, gate_vma); vma != NULL;
vma = next_vma(vma, gate_vma)) {
unsigned long addr;
unsigned long end;
end = vma->vm_start + vma_dump_size(vma, mm_flags);
for (addr = vma->vm_start; addr < end; addr += PAGE_SI...
struct page *page;
int stop;
page = get_dump_page(addr);
if (page) {
void *kaddr = kmap(page);
stop = ((size += PAGE_SIZE) > cprm->limit) ||
!dump_write(cprm->file, kaddr,
PAGE_SIZE);
kunmap(page);
page_cache_release(page);
} else
stop = !dump_seek(cprm->file, PAGE_SIZE);
if (stop)
goto end_coredump;
}
}
#ifdef ELF_CORE_WRITE_EXTRA_DATA
ELF_CORE_WRITE_EXTRA_DATA;
#endif
end_coredump:
set_fs(fs);
cleanup:
free_note_info(&info);
kfree(elf);
out:
return has_dumped;
}
*コメント [#d5ac3096]
終了行:
*参照元 [#g685cf4a]
#backlinks
*説明 [#va855e73]
-パス: [[linux-2.6.33/fs/binfmt_elf.c]]
-FIXME: これは何?
--説明
**引数 [#i963e8b1]
-
--
**返り値 [#qf442fb6]
-
--
**参考 [#edf5e669]
*実装 [#qc5e91f9]
/*
* Actual dumper
*
* This is a two-pass process; first we find the offsets...
* and then they are actually written out. If we run ou...
* we just truncate.
*/
static int elf_core_dump(struct coredump_params *cprm)
{
int has_dumped = 0;
mm_segment_t fs;
int segs;
size_t size = 0;
struct vm_area_struct *vma, *gate_vma;
struct elfhdr *elf = NULL;
loff_t offset = 0, dataoff, foffset;
unsigned long mm_flags;
struct elf_note_info info;
/*
* We no longer stop all VM operations.
*
* This is because those proceses that could possibly c...
* or the mmap / vma pages are now blocked in do_exit o...
* finishing this core dump.
*
* Only ptrace can touch these memory addresses, but it...
* the map_count or the pages allocated. So no possibil...
* exists while dumping the mm->vm_next areas to the co...
*/
/* alloc memory for large data structures: too large to...
elf = kmalloc(sizeof(*elf), GFP_KERNEL);
if (!elf)
goto out;
/*
* The number of segs are recored into ELF header as 16...
* Please check DEFAULT_MAX_MAP_COUNT definition when y...
*/
segs = current->mm->map_count;
#ifdef ELF_CORE_EXTRA_PHDRS
segs += ELF_CORE_EXTRA_PHDRS;
#endif
gate_vma = get_gate_vma(current);
if (gate_vma != NULL)
segs++;
/*
* Collect all the non-memory information about the pro...
* notes. This also sets up the file header.
*/
if (!fill_note_info(elf, segs + 1, /* including notes s...
&info, cprm->signr, cprm->regs))
goto cleanup;
has_dumped = 1;
current->flags |= PF_DUMPCORE;
fs = get_fs();
set_fs(KERNEL_DS);
DUMP_WRITE(elf, sizeof(*elf));
offset += sizeof(*elf); /* Elf header */
offset += (segs + 1) * sizeof(struct elf_phdr); /* Prog...
foffset = offset;
/* Write notes phdr entry */
{
struct elf_phdr phdr;
size_t sz = get_note_info_size(&info);
sz += elf_coredump_extra_notes_size();
fill_elf_note_phdr(&phdr, sz, offset);
offset += sz;
DUMP_WRITE(&phdr, sizeof(phdr));
}
dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE);
/*
* We must use the same mm->flags while dumping core to...
* inconsistency between the program headers and bodies...
* unusable core file can be generated.
*/
mm_flags = current->mm->flags;
/* Write program headers for segments dump */
for (vma = first_vma(current, gate_vma); vma != NULL;
vma = next_vma(vma, gate_vma)) {
struct elf_phdr phdr;
phdr.p_type = PT_LOAD;
phdr.p_offset = offset;
phdr.p_vaddr = vma->vm_start;
phdr.p_paddr = 0;
phdr.p_filesz = vma_dump_size(vma, mm_flags);
phdr.p_memsz = vma->vm_end - vma->vm_start;
offset += phdr.p_filesz;
phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
if (vma->vm_flags & VM_WRITE)
phdr.p_flags |= PF_W;
if (vma->vm_flags & VM_EXEC)
phdr.p_flags |= PF_X;
phdr.p_align = ELF_EXEC_PAGESIZE;
DUMP_WRITE(&phdr, sizeof(phdr));
}
#ifdef ELF_CORE_WRITE_EXTRA_PHDRS
ELF_CORE_WRITE_EXTRA_PHDRS;
#endif
/* write out the notes section */
if (!write_note_info(&info, cprm->file, &foffset))
goto end_coredump;
if (elf_coredump_extra_notes_write(cprm->file, &foffset))
goto end_coredump;
/* Align to page */
if (!dump_seek(cprm->file, dataoff - foffset))
goto end_coredump;
for (vma = first_vma(current, gate_vma); vma != NULL;
vma = next_vma(vma, gate_vma)) {
unsigned long addr;
unsigned long end;
end = vma->vm_start + vma_dump_size(vma, mm_flags);
for (addr = vma->vm_start; addr < end; addr += PAGE_SI...
struct page *page;
int stop;
page = get_dump_page(addr);
if (page) {
void *kaddr = kmap(page);
stop = ((size += PAGE_SIZE) > cprm->limit) ||
!dump_write(cprm->file, kaddr,
PAGE_SIZE);
kunmap(page);
page_cache_release(page);
} else
stop = !dump_seek(cprm->file, PAGE_SIZE);
if (stop)
goto end_coredump;
}
}
#ifdef ELF_CORE_WRITE_EXTRA_DATA
ELF_CORE_WRITE_EXTRA_DATA;
#endif
end_coredump:
set_fs(fs);
cleanup:
free_note_info(&info);
kfree(elf);
out:
return has_dumped;
}
*コメント [#d5ac3096]
ページ名: