[PATCH 1/2] x86_64: Reflect the relocatability of the kernel in the ELF header.

Eric W. Biederman ebiederm at xmission.com
Tue Apr 24 03:21:03 EDT 2007

Vivek Goyal <vgoyal at in.ibm.com> writes:

> On Sun, Apr 22, 2007 at 11:12:13PM -0600, Eric W. Biederman wrote:
>> Currently because vmlinux does not reflect that the kernel is relocatable
>> we still have to support CONFIG_PHYSICAL_START.  So this patch adds a small
>> c program to do what we cannot do with a linker script, set the elf header
>> type to ET_DYN.
>> This should remove the last obstacle to removing CONFIG_PHYSICAL_START
>> on x86_64.
>> Signed-off-by: Eric W. Biederman <ebiederm at xmission.com>
> [Dropping fastboot mailing list from CC as kexec mailing list is new list
>  for this discussion]
> [..]
>> +void file_open(const char *name)
>> +{
>> +	if ((fd = open(name, O_RDWR, 0)) < 0)
>> +		die("Unable to open `%s': %m", name);
>> +}
>> +
>> +static void mketrel(void)
>> +{
>> +	unsigned char e_type[2];
>> +	if (read(fd, &e_ident, sizeof(e_ident)) != sizeof(e_ident))
>> +		die("Cannot read ELF header: %s\n", strerror(errno));
>> +
>> +	if (memcmp(e_ident, ELFMAG, 4) != 0)
>> +		die("No ELF magic\n");
>> +
>> +	if ((e_ident[EI_CLASS] != ELFCLASS64) &&
>> +	    (e_ident[EI_CLASS] != ELFCLASS32))
>> +		die("Unrecognized ELF class: %x\n", e_ident[EI_CLASS]);
>> +	
>> +	if ((e_ident[EI_DATA] != ELFDATA2LSB) &&
>> +	    (e_ident[EI_DATA] != ELFDATA2MSB))
>> +		die("Unrecognized ELF data encoding: %x\n", e_ident[EI_DATA]);
>> +
>> +	if (e_ident[EI_VERSION] != EV_CURRENT)
>> +		die("Unknown ELF version: %d\n", e_ident[EI_VERSION]);
>> +
>> +	if (e_ident[EI_DATA] == ELFDATA2LSB) {
>> +		e_type[0] = ET_REL & 0xff;
>> +		e_type[1] = ET_REL >> 8;
>> +	} else {
>> +		e_type[1] = ET_REL & 0xff;
>> +		e_type[0] = ET_REL >> 8;
>> +	}
> Hi Eric,
> Should this be ET_REL or ET_DYN? kexec refuses to load this vmlinux
> as it does not find it to be executable type.

Doh.  It should be ET_DYN.  I had relocatable much to much on the brain,
and so I stuffed in the wrong type.

> I am not well versed with various conventions but if I go through "Executable
> and Linking Format" document, this is what it says about various file types.
> ¥ A relocatable file holds code and data suitable for linking with other
>   object files to create an executable or a shared object file.
> ¥ An executable file holds a program suitable for execution.
> ¥ A shared object file holds code and data suitable for linking in two
>   contexts. First, the link editor may process it with other relocatable and
>   shared object files to create another object file. Second, the dynamic
>   linker combines it with an executable file and other shared objects
>   to create a process image.
> So above does not seem to fit in the ET_REL type. We can't relink this
> vmlinux? And it does not seem to fit in ET_DYN definition too. We are
> not relinking this vmlinux with another executable or other relocatable
> files.
> I remember once you mentioned the term dynamic executable which can be
> loaded at a non-compiled address and let run without requiring any
> relocation processing. This vmlinux will fall in that category but can't 
> relate it to standard elf file definitions.

Sorry about that.  

ET_DYN without a PT_DYNAMIC segment, without a PT_INTERP segment,
and with a valid entry point is exactly that.  Loaders never perform
relocation processing on a ET_DYN executable but they are allowed to
shift all of the addresses by a single delta so long as all of the
alignment restrictions are honored.

Relocation processing when it happens comes from the dynamic linker,
which is set in PT_INTERP and the dynamic linker looks a PT_DYNAMIC
to figure out what relocations are available for processing.

The basic issue is that ld don't really comprehend what we are doing
since we are building a position independent executable in a way
that the normal tools don't allow, so we have to poke the header.

If we had compiled with -fPIC we could have specified -pie or
--pic-executable to ld and it would have done the right thing.
But as it is our executable only changes physical addresses and
not virtual addresses something completely foreign to ld.


More information about the kexec mailing list