[BACK]Return to clean-elf.c CVS log [TXT][DIR] Up to [local] / sys / arch / sparc / stand / common

File: [local] / sys / arch / sparc / stand / common / clean-elf.c (download)

Revision 1.1.1.1 (vendor branch), Tue Mar 4 16:07:53 2008 UTC (16 years, 4 months ago) by nbrk
Branch: OPENBSD_4_2_BASE, MAIN
CVS Tags: jornada-partial-support-wip, HEAD
Changes since 1.1: +0 -0 lines

Import of OpenBSD 4.2 release kernel tree with initial code to support 
Jornada 720/728, StrongARM 1110-based handheld PC.
At this point kernel roots on NFS and boots into vfs_mountroot() and traps.
What is supported:
- glass console, Jornada framebuffer (jfb) works in 16bpp direct color mode
(needs some palette tweaks for non black/white/blue colors, i think)
- saic, SA11x0 interrupt controller (needs cleanup)
- sacom, SA11x0 UART (supported only as boot console for now)
- SA11x0 GPIO controller fully supported (but can't handle multiple interrupt
handlers on one gpio pin)
- sassp, SSP port on SA11x0 that attaches spibus
- Jornada microcontroller (jmcu) to control kbd, battery, etc throught
the SPI bus (wskbd attaches on jmcu, but not tested)
- tod functions seem work
- initial code for SA-1111 (chip companion) : this is TODO

Next important steps, i think:
- gpio and intc on sa1111
- pcmcia support for sa11x0 (and sa1111 help logic)
- REAL root on nfs when we have PCMCIA support (we may use any of supported pccard NICs)
- root on wd0! (using already supported PCMCIA-ATA)

/*	$OpenBSD: clean-elf.c,v 1.2 2003/11/03 07:01:33 david Exp $	*/
/*
 * Public domain. I don't even want my name on this.
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <err.h>
#include <elf_abi.h>
#include <fcntl.h>

int
elf_is_okay(Elf_Ehdr *ehdr)
{
	int retval = 0;

	/*
	 * We need to check magic, class size, endianess,
	 * and version before we look at the rest of the
	 * Elf_Ehdr structure.  These few elements are
	 * represented in a machine independent fashion.
	 */

	if (IS_ELF(*ehdr) &&
	    ehdr->e_ident[EI_CLASS] == ELF_TARG_CLASS &&
	    ehdr->e_ident[EI_DATA] == ELF_TARG_DATA &&
	    ehdr->e_ident[EI_VERSION] == ELF_TARG_VER) {
		/* Now check the machine dependant header */
		if (ehdr->e_machine == ELF_TARG_MACH &&
		    ehdr->e_version == ELF_TARG_VER)
			retval = 1;
	}

	return retval;
}

void
cleanit(caddr_t addr)
{
	Elf_Ehdr *ehdr;
	Elf_Shdr *shdr;
	char *strtab;
	int i;

	ehdr = (Elf_Ehdr *)addr;
	shdr = (Elf_Shdr *)(addr + ehdr->e_shoff);

	strtab = shdr[ehdr->e_shstrndx].sh_offset + addr;

	/*
	 * Simple. find a .text section, verify that the next section is
	 * .rodata and merge them.
	 */

	for (i = 0; i < ehdr->e_shnum; i++) {
		Elf_Shdr *t = &shdr[i];
		Elf_Shdr *r = &shdr[i + 1];

#if 0
		printf("foo: %s %d\n", strtab + t->sh_name, t->sh_type);
		continue;
#endif
		if (strcmp(strtab + t->sh_name, ".text"))
			continue;
		if (strcmp(strtab + r->sh_name, ".rodata"))
			errx(1, "sorry, rodata merge not possible.");

		t->sh_size += r->sh_size + (r->sh_offset - t->sh_offset - t->sh_size);
		r->sh_type = SHT_NULL;
		r->sh_name = 0;
	}
}

int
main(int argc, char **argv)
{
	int fd;
	void *addr;
	off_t len;
	int pgsz = getpagesize();

	if (argc != 2)
		errx(1, "usage");

	if ((fd = open(argv[1], O_RDWR)) < 0)
		err(1, "open");

	if ((len = lseek(fd, 0, SEEK_END)) < 0)
		err(1, "lseek");

	len = ((len + pgsz - 1) & ~(pgsz - 1));

	if ((addr = mmap(0, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)) ==
	    MAP_FAILED)
		err(1, "mmap");

	if (!elf_is_okay((Elf_Ehdr *)addr))
		errx(1, "not an elf file");

	cleanit(addr);

	msync(addr, len, MS_SYNC|MS_INVALIDATE);

	close(fd);
	return (0);
}