[PATCH] vmcore-dmesg: Determine file data size based on e_machine

Eric W. Biederman ebiederm at xmission.com
Mon Nov 12 21:07:43 EST 2012


Vivek Goyal <vgoyal at redhat.com> writes:

> A 32bit arch can prepare ELF64 headers. For example for PAE case to
> preresent file offsets 64bit but data size at the offset still remains
> 32bit. If we just base our decision based on EI_CLASS, then we will try
> to read 64bit data from file and can run into various issues.
>
> We ran into following issue when we tried to run vmcore-dmesg on a 32bit
> PAE system vmcore which had 64bit elf headers.
>
> No program header covering vaddr 0xc0a6a688c0b89100found kexec bug?
>
> Basically we try to read value of log_buf variable from address
> log_buf_vaddr. We read in 64bit value and then pass that value again
> to vaddr_to_offset() in an attempt to get to actual log_buf start
> and get error message.
>
> So determine the data size based on arch and read the bytes from
> file accordingly.

The basic code change is sound.  However the naming is problematic.

Let me suggest:

static unsigned machine_pointer_bits(void)
{
        uint8_t bits = 0;

        /* Default to the size of the elf class */
        switch(ehdr.e_ident[EI_CLASS]) {
        case ELFCLASS32:	bits = 32; break;
        case ELFCLASS64:	bits = 64; break;
        }

        /* Report the architectures pointer size */
        switch(ehdr.e_machine) {
        case EM_386:		bits = 32; break;
        }

        return bits;
}


> Signed-off-by: Vivek Goyal <vgoyal at redhat.com>
> ---
>  vmcore-dmesg/vmcore-dmesg.c |   20 +++++++++++++++++++-
>  1 file changed, 19 insertions(+), 1 deletion(-)
>
> Index: kexec-tools/vmcore-dmesg/vmcore-dmesg.c
> ===================================================================
> --- kexec-tools.orig/vmcore-dmesg/vmcore-dmesg.c	2012-08-03 15:46:54.000000000 -0400
> +++ kexec-tools/vmcore-dmesg/vmcore-dmesg.c	2012-11-08 05:30:17.918099858 -0500
> @@ -89,6 +89,23 @@ static uint64_t vaddr_to_offset(uint64_t
>  	exit(30);
>  }
>  
> +/*
> + * For PAE arch, one can prepare 64bit ELF headers to make offsets 64bit in
> + * file but data size still remains 32bit. Determine data size based on arch
> + * (e_machine).
> + *
> + * returns 1 if arch passed in is 64bit
> + */
> +static bool file_data_size_64bit(unsigned int e_machine)
> +{
> +	switch(e_machine) {
> +		/* TODO: keep on adding 32bit arch to get vmcore-dmesg right */
> +		case EM_386:
> +			return 0;
> +	}
> +	return 1;
> +}
> +
>  static void read_elf32(int fd)
>  {
>  	Elf32_Ehdr ehdr32;
> @@ -389,7 +406,8 @@ static uint64_t read_file_pointer(int fd
>  {
>  	uint64_t result;
>  	ssize_t ret;
> -	if (ehdr.e_ident[EI_CLASS] == ELFCLASS64) {
> +	if (ehdr.e_ident[EI_CLASS] == ELFCLASS64 &&
> +	    file_data_size_64bit(ehdr.e_machine)) {
Then this test can become:
	if (machine_pointer_bits() == 64) {
>  		uint64_t scratch;
>  		ret = pread(fd, &scratch, sizeof(scratch), addr);
>  		if (ret != sizeof(scratch)) {



More information about the kexec mailing list