[U-Boot-Users] ELF Loader

Chris Elston elston at radstone.co.uk
Tue Feb 25 12:12:09 CET 2003


I've come across a problem using the ELF loader, the existing one relocates
the data in the ELF image using section headers.  This prevented a LynxOS
image I have being loaded correctly.  I was lead to believe by the ELF
standard that section headers are for linking, not loading and execution.  
I have reimplemented the ELF loader using program headers, this is shown in
the code snippet below.  (The original code is left in for reference but
commmented out)  Can anyone tell me if there is a valid reason for the way
it was done originally?  

Thanks,

Chris.

/* ======================================================================
 * A very simple elf loader, assumes the image is valid, returns the
 * entry point address.
 * ====================================================================== */
unsigned long load_elf_image (unsigned long addr)
{
	Elf32_Ehdr *ehdr;		/* Elf header structure pointer
*/
	Elf32_Shdr *shdr;		/* Section header structure pointer
*/
	Elf32_Phdr *phdr;		/* Program header structure pointer
*/
	unsigned char *strtab = 0;	/* String table pointer
*/
	unsigned char *image;		/* Binary image pointer
*/
	int i;				/* Loop counter
*/

	/* -------------------------------------------------- */

	ehdr = (Elf32_Ehdr *) addr;

	/*printf("ehdr->e_phnum = %d, ehdr->e_shnum %d\n", ehdr->e_phnum,
ehdr->e_shnum);*/

#if 0
	/* Find the section header string table for output info */
	shdr = (Elf32_Shdr *) (addr + ehdr->e_shoff +
			       (ehdr->e_shstrndx * sizeof (Elf32_Shdr)));

	if (shdr->sh_type == SHT_STRTAB)
		strtab = (unsigned char *) (addr + shdr->sh_offset);
#endif

	for (i = 0; i < ehdr->e_phnum; ++i) {
		phdr = (Elf32_Phdr *) (addr + ehdr->e_phoff +
						(i * sizeof (Elf32_Phdr)));

		if (phdr->p_vaddr == 0 || phdr->p_filesz == 0) {
			continue;
		}

		if (phdr->p_type == PT_LOAD) {
			image = (unsigned char *) addr + phdr->p_offset;
			/*printf("Copying %d bytes from %p to %p\n",
phdr->p_filesz, image, phdr->p_vaddr);*/
			printf("Relocating ELF data\n");
			memcpy ((void *) phdr->p_vaddr,
				(const void *) image,
				phdr->p_filesz);
		}
		flush_cache (phdr->p_vaddr, phdr->p_filesz);
	}

#if 0
	/* Load each appropriate section */
	for (i = 0; i < ehdr->e_shnum; ++i) {
		shdr = (Elf32_Shdr *) (addr + ehdr->e_shoff +
				       (i * sizeof (Elf32_Shdr)));

		if (!(shdr->sh_flags & SHF_ALLOC)
		   || shdr->sh_addr == 0 || shdr->sh_size == 0) {
			continue;
		}

		if (strtab) {
			printf ("%sing %s @ 0x%08lx (%ld bytes)\n",
				(shdr->sh_type == SHT_NOBITS) ?
					"Clear" : "Load",
				&strtab[shdr->sh_name],
				(unsigned long) shdr->sh_addr,
				(long) shdr->sh_size);
		}

		if (shdr->sh_type == SHT_NOBITS) {
			memset ((void *)shdr->sh_addr, 0, shdr->sh_size);
		} else {
			image = (unsigned char *) addr + shdr->sh_offset;
			memcpy ((void *) shdr->sh_addr,
				(const void *) image,
				shdr->sh_size);
		}
		flush_cache (shdr->sh_addr, shdr->sh_size);
	}
#endif

	return ehdr->e_entry;
}

============================
Chris Elston
Software Engineer,
Processors Group,
Radstone Technology,
============================
mailto:elston at radstone.co.uk
============================

________________________________________________________________________
This e-mail has been scanned for all viruses by Star Internet. The
service is powered by MessageLabs. For more information on a proactive
anti-virus service working around the clock, around the globe, visit:
http://www.star.net.uk
________________________________________________________________________




More information about the U-Boot mailing list