diff options
| author | Tony Lindgren <tony@atomide.com> | 2011-11-07 12:27:23 -0800 | 
|---|---|---|
| committer | Tony Lindgren <tony@atomide.com> | 2011-11-07 12:27:23 -0800 | 
| commit | d30cc16c8e48368e0518f4975a78711e53e14a0f (patch) | |
| tree | 26b57f7ab5a963cc3d6c57dff6951bd930875583 /arch/x86/um/elfcore.c | |
| parent | 41eb2d813f558900884e240c2f723e36c7bd151f (diff) | |
| parent | a1bcc1dcef8451b4291ea2a1b2677cb194102952 (diff) | |
Merge branch 'fixes-modulesplit' into fixes
Diffstat (limited to 'arch/x86/um/elfcore.c')
| -rw-r--r-- | arch/x86/um/elfcore.c | 83 | 
1 files changed, 83 insertions, 0 deletions
| diff --git a/arch/x86/um/elfcore.c b/arch/x86/um/elfcore.c new file mode 100644 index 000000000000..6bb49b687c97 --- /dev/null +++ b/arch/x86/um/elfcore.c @@ -0,0 +1,83 @@ +#include <linux/elf.h> +#include <linux/coredump.h> +#include <linux/fs.h> +#include <linux/mm.h> + +#include <asm/elf.h> + + +Elf32_Half elf_core_extra_phdrs(void) +{ +	return vsyscall_ehdr ? (((struct elfhdr *)vsyscall_ehdr)->e_phnum) : 0; +} + +int elf_core_write_extra_phdrs(struct file *file, loff_t offset, size_t *size, +			       unsigned long limit) +{ +	if ( vsyscall_ehdr ) { +		const struct elfhdr *const ehdrp = +			(struct elfhdr *) vsyscall_ehdr; +		const struct elf_phdr *const phdrp = +			(const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff); +		int i; +		Elf32_Off ofs = 0; + +		for (i = 0; i < ehdrp->e_phnum; ++i) { +			struct elf_phdr phdr = phdrp[i]; + +			if (phdr.p_type == PT_LOAD) { +				ofs = phdr.p_offset = offset; +				offset += phdr.p_filesz; +			} else { +				phdr.p_offset += ofs; +			} +			phdr.p_paddr = 0; /* match other core phdrs */ +			*size += sizeof(phdr); +			if (*size > limit +			    || !dump_write(file, &phdr, sizeof(phdr))) +				return 0; +		} +	} +	return 1; +} + +int elf_core_write_extra_data(struct file *file, size_t *size, +			      unsigned long limit) +{ +	if ( vsyscall_ehdr ) { +		const struct elfhdr *const ehdrp = +			(struct elfhdr *) vsyscall_ehdr; +		const struct elf_phdr *const phdrp = +			(const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff); +		int i; + +		for (i = 0; i < ehdrp->e_phnum; ++i) { +			if (phdrp[i].p_type == PT_LOAD) { +				void *addr = (void *) phdrp[i].p_vaddr; +				size_t filesz = phdrp[i].p_filesz; + +				*size += filesz; +				if (*size > limit +				    || !dump_write(file, addr, filesz)) +					return 0; +			} +		} +	} +	return 1; +} + +size_t elf_core_extra_data_size(void) +{ +	if ( vsyscall_ehdr ) { +		const struct elfhdr *const ehdrp = +			(struct elfhdr *)vsyscall_ehdr; +		const struct elf_phdr *const phdrp = +			(const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff); +		int i; + +		for (i = 0; i < ehdrp->e_phnum; ++i) +			if (phdrp[i].p_type == PT_LOAD) +				return (size_t) phdrp[i].p_filesz; +	} +	return 0; +} | 
