don't get too scared about the subject line. 

LAR is a very capable format. With two simple extensions, we can use LAR to replace all that we are using ELF for now. This change can really make life better:
1. we can use streaming decompress instead of the current "uncompress elf to memory and then copy segments" approach. So we can get rid of THIS hardcode:
#define UNCOMPRESS_AREA (0x400000)
2. A simple lar l can show ALL segments, including payload segments
3. It's really easy to see where things will go in memory, and catch problems
4. We can figure out an ELF input file is bogus BEFORE we flash, not AFTER we flash and try to boot it
5. did I mention streaming decompress? 
6. We no longer have to worry about where we decompress the elf in memory (this problem was causing trouble when the payload was a linux kernel -- it was so big)
7. Since we have a load address, we can create this lar entry:
normal/cmdline 
and specify that it be loaded at a place where linux will find it as the cmdline. 
8. The decision on whether to XIP can be made in the LAR entry, not in hardcode. For example, if initram needs to be XIP, set the load address to 0xffffffff. Done. 

The change is simple. Add a load address and entry point to the lar header. Extend the lar tool to parse the elf file and create multiple lar segments. It looks like this:
  normal/payload0 (33192 bytes, lzma compressed to 18088 bytes @0x38 load @0x100000, entry 0x105258)
  normal/payload1 (72 bytes, lzma compressed to 47 bytes @0x4718 load @0x1225a0, entry 0x105258)
  normal/option_table (932 bytes @0x4798 load @0, entry 0)
  normal/stage2 (33308 bytes, lzma compressed to 15474 bytes @0x4b78 load @0, entry 0)
  normal/initram (4208 bytes @0x8828 load @0, entry 0)
  linuxbios.bootblock (16384 bytes @0xfc000 load @0, entry 0)

note that the payload is now payload0, payload1, etc. I've extended linuxbios to look for these. Note that you can now see all the things that get loaded ;they're no longer hidden in an ELF header somewhere. Elf failures are gone!

Note that I've left legacy elf support in, for now, but recommend we get rid of it as soon as possible. 
Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
Index: include/lar.h
===================================================================
--- include/lar.h	(revision 464)
+++ include/lar.h	(working copy)
@@ -54,7 +54,7 @@
 
 #define MAGIC "LARCHIVE"
 #define MAX_PATHLEN 1024
-
+/* NOTE -- This and the user-mode lar.h are NOT IN SYNC. Be careful. */
 struct lar_header {
 	char magic[8];
 	u32 len;
@@ -62,6 +62,13 @@
 	u32 checksum;
 	u32 compchecksum;
 	u32 offset;
+	u32 entry;		/* we might need to make this u64 */
+	u32 loadaddress; /* ditto */
+	/* Compression:
+	 * 0 = no compression
+	 * 1 = lzma
+	 * 2 = nrv2b
+	 */
 	u32 compression;
 };
 
@@ -69,6 +76,8 @@
 	void *start;
 	int len;
 	u32 reallen;
+	void * entry;
+	void * loadaddress;
 	u32 compression;
 };
 
@@ -77,5 +86,6 @@
 int copy_file(struct mem_file *archive, char *filename, void *where);
 int run_file(struct mem_file *archive, char *filename, void *where);
 int execute_in_place(struct mem_file *archive, char *filename);
-
+int run_address(void *f);
+void * load_file(struct mem_file *archive, char *filename);
 #endif /* LAR_H */
Index: mainboard/emulation/qemu-x86/initram.c
===================================================================
--- mainboard/emulation/qemu-x86/initram.c	(revision 464)
+++ mainboard/emulation/qemu-x86/initram.c	(working copy)
@@ -19,10 +19,12 @@
 
 #include <console.h>
 
+int (*pk)(int msg_level, const char *fmt, ...) = printk;
+
 int main(void)
 {
-	printk(BIOS_INFO, "RAM init code started.\n");
-	printk(BIOS_INFO, "Nothing to do.\n");
+	pk(BIOS_INFO, "RAM init code started.\n");
+	pk(BIOS_INFO, "Nothing to do.\n");
 
 	return 0;
 }
Index: mainboard/emulation/qemu-x86/Makefile
===================================================================
--- mainboard/emulation/qemu-x86/Makefile	(revision 464)
+++ mainboard/emulation/qemu-x86/Makefile	(working copy)
@@ -41,14 +41,17 @@
 #
 
 INITRAM_OBJ = $(obj)/mainboard/$(MAINBOARDDIR)/initram.o
+$(obj)/mainboard/$(MAINBOARDDIR)/initram.o: $(src)/mainboard/$(MAINBOARDDIR)/initram.c
+	cc -c $(INITCFLAGS)  -fPIE $(src)/mainboard/$(MAINBOARDDIR)/initram.c -o $(obj)/mainboard/$(MAINBOARDDIR)/initram.o
+
 # These are possibly not permanent
-INITRAM_OBJ += $(obj)/lib/console.o $(obj)/lib/vtxprintf.o $(obj)/lib/uart8250.o $(obj)/arch/x86/post_code.o
+#INITRAM_OBJ += $(obj)/lib/console.o $(obj)/lib/vtxprintf.o $(obj)/lib/uart8250.o $(obj)/arch/x86/post_code.o
 
 $(obj)/linuxbios.initram: $(obj)/stage0.init $(obj)/stage0.o $(INITRAM_OBJ)
 	$(Q)# initram links against stage0
 	$(Q)printf "  LD      $(subst $(shell pwd)/,,$(@))\n"
-	$(Q)$(LD)  -Ttext 0x80000 $(INITRAM_OBJ) \
-		--entry=main -o $(obj)/linuxbios.initram.o
+	$(Q)$(LD)  $(INITRAM_OBJ) \
+		--entry=main -R $(obj)/stage0.o -o $(obj)/linuxbios.initram.o
 	$(Q)printf "  OBJCOPY $(subst $(shell pwd)/,,$(@))\n"
 	$(Q)$(OBJCOPY) -O binary $(obj)/linuxbios.initram.o \
 		$(obj)/linuxbios.initram
Index: lib/lzmadecode.c
===================================================================
--- lib/lzmadecode.c	(revision 464)
+++ lib/lzmadecode.c	(working copy)
@@ -206,7 +206,6 @@
         RC_GET_BIT(probLit, symbol)
       }
       previousByte = (Byte)symbol;
-
       outStream[nowPos++] = previousByte;
       if (state < 4) state = 0;
       else if (state < 10) state -= 3;
Index: lib/lar.c
===================================================================
--- lib/lar.c	(revision 464)
+++ lib/lar.c	(working copy)
@@ -31,6 +31,13 @@
 #define ntohl(x) (x)
 #endif
 
+int run_address(void *f)
+{
+	int (*v) (void);
+	v = f;
+	return v();
+}
+
 int find_file(struct mem_file *archive, char *filename, struct mem_file *result)
 {
 	char *walk, *fullname;
@@ -52,19 +59,69 @@
 		// FIXME: check checksum
 
 		if (strcmp(fullname, filename) == 0) {
+			printk(BIOS_SPEW, "LAR: it matches %s @ %p\n", fullname, header);
 			result->start = walk + ntohl(header->offset);
 			result->len = ntohl(header->len);
 			result->reallen = ntohl(header->reallen);
 			result->compression = ntohl(header->compression);
+			result->entry = (void *)ntohl(header->entry);
+			result->loadaddress = (void *)ntohl(header->loadaddress);
+			printk(BIOS_SPEW, "start %p len %d reallen %d compression %x entry %p loadaddress %p\n", 
+				result->start, result->len, result->reallen, result->compression, result->entry, result->loadaddress);
 			return 0;
 		}
 		// skip file
 		walk += (ntohl(header->len) + ntohl(header->offset) -
 			1) & 0xfffffff0;
 	}
+	printk(BIOS_SPEW, "NO FILE FOUND\n");
 	return 1;
 }
 
+
+void * load_file(struct mem_file *archive, char *filename)
+{
+	int ret;
+	struct mem_file result;
+	void *where;
+	void *entry;
+
+	ret = find_file(archive, filename, &result);
+	if (ret) {
+		printk(BIOS_INFO, "LAR: load_file: No such file '%s'\n",
+		       filename);
+		return (void *)-1;
+	}
+	entry = result.entry;
+	where = result.loadaddress;
+	printk(BIOS_SPEW, "LAR: Compression algorithm #%i used\n", result.compression);
+	/* no compression */
+	if (result.compression == 0) {
+		memcpy(where, result.start, result.len);
+		return entry;
+	}
+#ifdef CONFIG_COMPRESSION_LZMA
+	/* lzma */
+	unsigned long ulzma(unsigned char * src, unsigned char * dst);
+	if (result.compression == 1) {
+		ulzma(result.start, where);
+		return entry;
+	}
+#endif
+#ifdef CONFIG_COMPRESSION_NRV2B
+	/* nrv2b */
+	unsigned long unrv2b(u8 * src, u8 * dst, unsigned long *ilen_p);
+	if (result.compression == 2) {
+		int tmp;
+		unrv2b(result.start, where, &tmp);
+		return entry;
+	}
+#endif
+	printk(BIOS_INFO, "LAR: Compression algorithm #%i not supported!\n", result.compression);
+	return (void *)-1;
+}
+
+/* FIXME -- most of copy_file should be replaced by load_file */
 int copy_file(struct mem_file *archive, char *filename, void *where)
 {
 	int ret;
@@ -113,6 +170,7 @@
 {
 	int (*v) (void);
 	struct mem_file result;
+	int ret;
 
 	if ((u32) where != 0xFFFFFFFF) {
 		if (copy_file(archive, filename, where)) {
@@ -130,9 +188,11 @@
 		}
 		where = result.start;
 	}
-
+	printk(BIOS_SPEW, "where is %p\n", where);
 	v = where;
-	return v();
+	ret =  v();
+	printk(BIOS_SPEW, "run_file returns with %d\n", ret);
+	return ret;
 }
 
 /**
Index: lib/stage2.c
===================================================================
--- lib/stage2.c	(revision 464)
+++ lib/stage2.c	(working copy)
@@ -96,8 +96,10 @@
 
 	/* TODO: Add comment. */
 	post_code(0x70);
-	write_tables();
+#warning WRITE_TABLES IS FAILING -- FIX ME IT IS DISABLED
+//	write_tables();
 	show_all_devs();
 
+	printk(BIOS_SPEW, "STAGE2 NOW RETURNING\n");
 	return 0;
 }
Index: arch/x86/stage1.c
===================================================================
--- arch/x86/stage1.c	(revision 464)
+++ arch/x86/stage1.c	(working copy)
@@ -22,12 +22,16 @@
 #include <io.h>
 #include <console.h>
 #include <lar.h>
+#include <string.h>
 #include <tables.h>
 #include <lib.h>
 #include <mc146818rtc.h>
 #include <post_code.h>
 
-#define UNCOMPRESS_AREA 0x60000
+/* ah, well, what a mess! This is a hard code. FIX ME but how? By having a "bounding box"
+ * for the payload, set in LAR, and just uncompressing PAST the payload 
+ */
+#define UNCOMPRESS_AREA (0x400000)
 
 /* these prototypes should go into headers */
 void uart_init(void);
@@ -48,6 +52,24 @@
 	post_code(0xf2);
 }
 
+
+/* until we get rid of elf */
+int legacy(struct mem_file *archive, char *name,  void *where, struct lb_memory *mem)
+{
+	int ret;
+	struct mem_file result;
+	int elfboot_mem(struct lb_memory *mem, void *where, int size);
+	ret = copy_file(archive, name, where);
+	if (ret) {
+		printk(BIOS_ERR, "'%s' found, but could not load it.\n", name);
+	}
+
+	ret =  elfboot_mem(mem, where, result.reallen);
+
+	printk(BIOS_ERR, "elfboot_mem returns %d\n", ret);
+	return -1;
+}
+
 /*
  * This function is called from assembler code whith its argument on the
  * stack. Force the compiler to generate always correct code for this case.
@@ -57,6 +79,8 @@
 	int ret;
 	struct mem_file archive, result;
 	int elfboot_mem(struct lb_memory *mem, void *where, int size);
+	void *entry;
+	int i;
 
 	/* we can't statically init this hack. */
 	unsigned char faker[64];
@@ -144,20 +168,32 @@
 	printk(BIOS_DEBUG, "Stage2 code done.\n");
 
 	ret = find_file(&archive, "normal/payload", &result);
-	if (ret) {
-		printk(BIOS_ERR, "No such file '%s'.\n", "normal/payload");
-		die("FATAL: No payload found.\n");
+	if (! ret)
+		legacy(&archive, "normal/payload", (void *)UNCOMPRESS_AREA, mem);
+
+
+	/* new style lar boot. Install all the files in memory. 
+	  * By convention we take the entry point from the first 
+	  * one. Look for a cmdline as well. 
+	  */
+	for(i = 0, entry = (void *)0; ;i++) {
+		char filename[64];
+		void *newentry;
+		sprintf(filename, "normal/payload%d", i);
+		archive.len = *(u32 *)0xfffffff4;
+		archive.start =(void *)(0UL-archive.len);
+		newentry = load_file(&archive, filename);
+		printk("newentry is %p\n", newentry);
+		if (newentry == (void *)-1)
+			break;
+		if (! entry)
+			entry = newentry;
 	}
-	ret = copy_file(&archive, "normal/payload", (void *)UNCOMPRESS_AREA);
-	if (ret) {
-		printk(BIOS_ERR, "'%s' found, but could not load it.\n", "normal/payload");
-		die("FATAL: No usable payload found.\n");
-	}
+	printk(BIOS_SPEW, "all loaded, entry %p\n", entry);
+	run_address(entry);
 
-	ret =  elfboot_mem(mem, (void *)UNCOMPRESS_AREA, result.reallen);
+	die("FATAL: No usable payload found.\n");
 
-	printk(BIOS_ERR, "elfboot_mem returns %d\n", ret);
-
 	die ("FATAL: Last stage returned to LinuxBIOS.\n");
 }
 
Index: arch/x86/Makefile
===================================================================
--- arch/x86/Makefile	(revision 464)
+++ arch/x86/Makefile	(working copy)
@@ -22,7 +22,7 @@
 ifeq ($(CONFIG_ARCH_X86),y)
 
 INITCFLAGS := $(CFLAGS) -I$(src)/include/arch/x86 -I$(src)/include \
-		-I$(obj) -fno-builtin
+		-I$(obj) -fno-builtin  
 
 SILENT := >/dev/null 2>&1
 
@@ -77,7 +77,7 @@
 	fi
 endif
 	$(Q)printf "  LAR     $(subst $(shell pwd)/,,$(@))\n"
-	$(Q)cd $(obj)/lar.tmp && ../util/lar/lar $(COMPRESSFLAG) -c \
+	$(Q)cd $(obj)/lar.tmp && ../util/lar/lar -p $(COMPRESSFLAG) -c \
 		../linuxbios.rom \
 		$(LARFILES) \
 		-s $(ROM_SIZE) -b $(obj)/linuxbios.bootblock
@@ -142,6 +142,9 @@
 	$(Q)printf "  OBJCOPY $(subst $(shell pwd)/,,$(@))\n"
 	$(Q)$(OBJCOPY) -O binary $(obj)/stage0.o $(obj)/stage0.init
 
+	$(Q)printf " OBJCOPY (stage0 link) $(subst $(shell pwd)/,,$(@))\n"
+	$(Q)$(OBJCOPY) --prefix-symbols=stage0 $(obj)/stage0.o $(obj)/stage0_link.o
+
 	$(Q)printf "  TEST    $(subst $(shell pwd)/,,$(@))\n"
 	$(Q)test `wc -c < $(obj)/stage0.init` -gt 16128 && \
 		printf "Error. Bootblock got too big.\n" || true
Index: util/lar/lar.c
===================================================================
--- util/lar/lar.c	(revision 464)
+++ util/lar/lar.c	(working copy)
@@ -37,6 +37,7 @@
 #define COPYRIGHT "Copyright (C) 2006-2007 coresystems GmbH"
 
 static int isverbose = 0;
+static int isparseelf = 0;
 static long larsize = 0;
 static char *bootblock = NULL;
 enum compalgo algo = none;
@@ -44,9 +45,14 @@
 static void usage(char *name)
 {
 	printf("\nLAR - the LinuxBIOS Archiver " VERSION "\n" COPYRIGHT "\n\n"
-	       "Usage: %s [-cxl] archive.lar [[[file1] file2] ...]\n\n", name);
+	       "Usage: %s [-ecxl] archive.lar [[[file1] file2] ...]\n\n", name);
 }
 
+int parseelf(void)
+{
+	return isparseelf;
+}
+
 int verbose(void)
 {
 	return isverbose;
@@ -78,6 +84,7 @@
 		{"list", 0, 0, 'l'},
 		{"size", 1, 0, 's'},
 		{"bootblock", 1, 0, 'b'},
+		{"parseelf", 1, 0, 'p'},
 		{"verbose", 0, 0, 'v'},
 		{"version", 0, 0, 'V'},
 		{"help", 0, 0, 'h'},
@@ -89,7 +96,7 @@
 		exit(1);
 	}
 
-	while ((opt = getopt_long(argc, argv, "cC:xls:b:vVh?",
+	while ((opt = getopt_long(argc, argv, "cC:xlps:b:vVh?",
 				  long_options, &option_index)) != EOF) {
 		switch (opt) {
 		case 'c':
@@ -106,6 +113,9 @@
 		case 'l':
 			larmode = LIST;
 			break;
+		case 'p':
+			isparseelf = 1;
+			break;
 		case 'x':
 			larmode = EXTRACT;
 			break;
Index: util/lar/create.c
===================================================================
--- util/lar/create.c	(revision 464)
+++ util/lar/create.c	(working copy)
@@ -18,7 +18,6 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
  */
-
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -30,6 +29,7 @@
 #include <sys/mman.h>
 #include <netinet/in.h>
 #include <libgen.h>
+#include <elf.h>
 
 #include "lib.h"
 #include "lar.h"
@@ -49,6 +49,201 @@
 	out_len[0] = in_len;
 }
 
+char *readfile(char *name, int *plen)
+{
+	int ret, filelen;
+	FILE *source;
+	char *filebuf;
+	struct stat statbuf;
+	*plen = -1;
+	ret = stat(name, &statbuf);
+	if (ret) {
+		fprintf(stderr, "No such file %s\n", name);
+		exit(1);
+	}
+	filelen = statbuf.st_size;
+	/* Read file into memory. */
+	filebuf = malloc(filelen);
+	source = fopen(name, "r");
+	if (!source) {
+		fprintf(stderr, "No such file %s\n", name);
+		exit(1);
+	}
+	fread(filebuf, filelen, 1, source);
+	fclose(source);
+	*plen = filelen;
+	return filebuf;
+}
+
+/* given an output file name, with data pointed to by filebuf, of size filelen,
+  * output it to the lar define by FILE *lar
+  */
+int
+outputfile(char *name, char *filebuf, int filelen, enum compalgo algo, FILE *archive, u32 entry, u32 loadaddress)
+{
+	char *pathname;
+	int i, ret;
+	int diff = 0;
+	int bb_header_len = 0;
+	FILE *source;
+	char *filetarget;
+	u32 *walk;
+	u32 csum;
+	int pathlen, entrylen;
+	u32 compfilelen;
+	long currentsize = 0;
+	struct lar_header *header;
+	enum compalgo thisalgo;
+	char *tempmem;
+	thisalgo = algo;
+	int tempsize = sizeof(struct lar_header) + MAX_PATHLEN + filelen + 16;
+		tempmem = malloc(tempsize);
+		if (!tempmem) {
+			fprintf(stderr, "Out of memory.\n");
+			return (-1);
+		}
+		memset(tempmem, 0, tempsize);
+		header = (struct lar_header *)tempmem;
+		pathname = tempmem + sizeof(struct lar_header);
+		pathlen = snprintf(pathname, MAX_PATHLEN - 1, name) + 1;
+		pathlen = (pathlen + 15) & 0xfffffff0;	/* Align to 16 bytes. */
+
+		filetarget = pathname + pathlen;
+		compress_functions[thisalgo](filebuf, filelen, filetarget,
+					     &compfilelen);
+		if ((compfilelen >= filelen) && (thisalgo != none)) {
+			thisalgo = none;
+			compress_functions[thisalgo](filebuf, filelen,
+						     filetarget, &compfilelen);
+		}
+
+		/* Create correct header. */
+		memcpy(header, MAGIC, 8);
+		header->compression = htonl(thisalgo);
+		header->entry = htonl(entry);
+		header->loadaddress = htonl(loadaddress);
+		header->reallen = htonl(filelen);
+		header->len = htonl(compfilelen);
+		header->offset = htonl(sizeof(struct lar_header) + pathlen);
+		/* Calculate checksum. */
+		csum = 0;
+		for (walk = (u32 *) tempmem;
+		     walk < (u32 *) (tempmem + compfilelen +
+				     sizeof(struct lar_header) + pathlen);
+		     walk++) {
+			csum += ntohl(*walk);
+		}
+		header->checksum = htonl(csum);
+		/* Write out entry to archive. */
+		entrylen = (compfilelen + pathlen + sizeof(struct lar_header) +
+			    15) & 0xfffffff0;
+
+		fwrite(tempmem, entrylen, 1, archive);
+		free(tempmem);
+	return entrylen;
+}
+
+/* the elf people are just plain dumb. See all the 32 stuff. */
+int output_elf_segments(char *name, char *filebuf, int filelen, enum compalgo algo, FILE *archive, Elf32_Ehdr *ehdr, int headers)
+{
+        Elf32_Phdr *phdr;
+	u32 entry;
+	int i;
+	int size;
+	int total = 0, thisph = 0;
+	unsigned char *header = (unsigned char *)ehdr;
+	char ename[64];
+
+        phdr = (Elf32_Phdr *)&(header[ehdr->e_phoff]);
+
+	fprintf(stderr, "%s: header %p #headers %d\n", __FUNCTION__, ehdr, headers);
+	entry = ehdr->e_entry;
+	for(i = 0; i < headers; i++) {
+		/* Ignore data that I don't need to handle */
+		if (phdr[i].p_type != PT_LOAD) {
+			fprintf(stderr, "Dropping non PT_LOAD segment\n");
+			continue;
+		}
+		if (phdr[i].p_memsz == 0) {
+			fprintf(stderr, "Dropping empty segment\n");
+			continue;
+		}
+		fprintf(stderr,  "New segment addr 0x%ulx size 0x%ulx offset 0x%ulx filesize 0x%ulx\n",
+			(u32)phdr[i].p_paddr, (u32)phdr[i].p_memsz, (u32)phdr[i].p_offset, (u32)phdr[i].p_filesz);
+		/* Clean up the values */
+		size = phdr[i].p_filesz;
+		if (phdr[i].p_filesz > phdr[i].p_memsz)  {
+			size = phdr[i].p_memsz;
+		}
+		fprintf(stderr, "(cleaned up) New segment addr %p size 0x%#x offset 0x%x\n",
+			(void *)phdr[i].p_paddr, size, phdr[i].p_offset);
+		/* ok, copy it out */
+		fprintf(stderr, "Copy to %p from %p for %d bytes\n", (unsigned char *)phdr[i].p_paddr, &header[phdr[i].p_offset], size);
+		fprintf(stderr, "entry %#lx loadaddr %#lx\n", 
+				entry,  phdr[i].p_paddr);
+		sprintf(ename, "%s%d", name, i);
+		thisph = outputfile(ename,  &header[phdr[i].p_offset], size, algo, archive, entry, phdr[i].p_paddr );
+		if (thisph < 0)
+			goto out;
+		total += thisph;		
+	}
+	return total;
+ out:
+	return -1;
+}
+
+
+int iself(char *filebuf)
+{
+	Elf32_Ehdr *ehdr;
+	/* validate elf header */
+	ehdr = (Elf32_Ehdr *)filebuf;
+	if (memcmp(ehdr->e_ident, ELFMAG, 4))
+		return 0;
+	return 1;
+}
+
+int
+outputelf(char *name, char *filebuf, int filelen, enum compalgo algo, FILE *archive)
+{
+	int index;
+	char *entryname;
+	Elf32_Ehdr *ehdr;
+	int header_offset;
+	int result;
+
+	/* validate elf header */
+	ehdr = (Elf32_Ehdr *)filebuf;
+	fprintf(stderr, "Type %d machine %d version %d entry %p phoff %d shoff %d flags %#x hsize %d phentsize %d phnum %d s_hentsize %d s_shnum %d \n", 
+		ehdr->e_type,
+		ehdr->e_machine,
+		ehdr->e_version,
+		(void *)ehdr->e_entry,
+		ehdr->e_phoff,
+		ehdr->e_shoff,
+		ehdr->e_flags,
+		ehdr->e_ehsize,
+		ehdr->e_phentsize,
+		ehdr->e_phnum,
+		ehdr->e_shentsize,
+		ehdr->e_shnum);
+
+		/* Sanity check the elf header */
+		if ((ehdr->e_type == ET_EXEC) &&
+//			elf_check_arch(ehdr) &&
+			(ehdr->e_ident[EI_VERSION] == EV_CURRENT) &&
+			(ehdr->e_version == EV_CURRENT) &&
+			(ehdr->e_ehsize == sizeof(Elf32_Ehdr)) &&
+			(ehdr->e_phentsize = sizeof(Elf32_Phdr))) {
+			/* we are ok ... */
+		} else {
+			fprintf(stderr, "%s failed sanity check\n", name);
+			return -1;
+		}
+
+	return output_elf_segments(name, filebuf, filelen,  algo,archive, ehdr, ehdr->e_phnum);
+}
+
 int create_lar(const char *archivename, struct file *files)
 {
 	int i, ret;
@@ -64,7 +259,6 @@
 	u32 compfilelen;
 	long currentsize = 0;
 	struct lar_header *header;
-	struct stat statbuf;
 	enum compalgo thisalgo;
 
 	if (!files) {
@@ -99,71 +293,15 @@
 		if (verbose())
 			printf("  Adding %s to archive\n", name);
 
-		ret = stat(name, &statbuf);
-		if (ret) {
-			fprintf(stderr, "No such file %s\n", name);
-			exit(1);
-		}
-		filelen = statbuf.st_size;
+		filebuf = readfile(name, &filelen);
 
-		tempmem = malloc(sizeof(struct lar_header) + MAX_PATHLEN
-				 + filelen + 16);
-		if (!tempmem) {
-			fprintf(stderr, "Out of memory.\n");
-			return (1);
-		}
-		memset(tempmem, 0, sizeof(struct lar_header) + MAX_PATHLEN
-		       + filelen + 16);
-
-		header = (struct lar_header *)tempmem;
-		pathname = tempmem + sizeof(struct lar_header);
-		pathlen = snprintf(pathname, MAX_PATHLEN - 1, name) + 1;
-		pathlen = (pathlen + 15) & 0xfffffff0;	/* Align to 16 bytes. */
-
-		/* Read file into memory. */
-		filebuf = malloc(filelen);
-		filetarget = pathname + pathlen;
-		source = fopen(name, "r");
-		if (!source) {
-			fprintf(stderr, "No such file %s\n", name);
-			exit(1);
-		}
-		fread(filebuf, filelen, 1, source);
-		fclose(source);
-		compress_functions[thisalgo](filebuf, filelen, filetarget,
-					     &compfilelen);
-		if ((compfilelen >= filelen) && (thisalgo != none)) {
-			thisalgo = none;
-			compress_functions[thisalgo](filebuf, filelen,
-						     filetarget, &compfilelen);
-		}
+		if (parseelf() && iself(filebuf))
+			entrylen = outputelf(name,filebuf, filelen, thisalgo,archive);
+		else
+			entrylen = outputfile(name,filebuf, filelen, thisalgo,archive, 0, 0);
 		free(filebuf);
-
-		/* Create correct header. */
-		memcpy(header, MAGIC, 8);
-		header->compression = htonl(thisalgo);
-		header->reallen = htonl(filelen);
-		header->len = htonl(compfilelen);
-		header->offset = htonl(sizeof(struct lar_header) + pathlen);
-
-		/* Calculate checksum. */
-		csum = 0;
-		for (walk = (u32 *) tempmem;
-		     walk < (u32 *) (tempmem + compfilelen +
-				     sizeof(struct lar_header) + pathlen);
-		     walk++) {
-			csum += ntohl(*walk);
-		}
-		header->checksum = htonl(csum);
-
-		/* Write out entry to archive. */
-		entrylen = (compfilelen + pathlen + sizeof(struct lar_header) +
-			    15) & 0xfffffff0;
-
-		fwrite(tempmem, entrylen, 1, archive);
-
-		free(tempmem);
-
+		if (entrylen < 0)
+			return 1;
 		/* size counter */
 		currentsize += entrylen;
 
Index: util/lar/lar.h
===================================================================
--- util/lar/lar.h	(revision 464)
+++ util/lar/lar.h	(working copy)
@@ -57,6 +57,7 @@
 
 typedef uint32_t u32;
 
+/* NOTE -- This and the linuxbios lar.h are NOT IN SYNC. Be careful. */
 struct lar_header {
 	char magic[8];
 	u32 len;
@@ -64,6 +65,8 @@
 	u32 checksum;
 	u32 compchecksum;
 	u32 offset;
+	u32 entry;		/* we might need to make this u64 */
+	u32 loadaddress; /* ditto */
 	/* Compression:
 	 * 0 = no compression
 	 * 1 = lzma
Index: util/lar/lib.h
===================================================================
--- util/lar/lib.h	(revision 464)
+++ util/lar/lib.h	(working copy)
@@ -37,6 +37,7 @@
 
 /* prototypes for lar.c functions */
 int verbose(void);
+int parseelf(void);
 long get_larsize(void);
 char *get_bootblock(void);
 
Index: util/lar/list.c
===================================================================
--- util/lar/list.c	(revision 464)
+++ util/lar/list.c	(working copy)
@@ -93,20 +93,22 @@
 		printf("  %s ", walk + sizeof(struct lar_header));
 
 		if (ntohl(header->compression) == none) {
-			printf("(%d bytes @0x%lx)\n",
+			printf("(%d bytes @0x%lx load @%#x, entry %#x)\n",
 			       ntohl(header->len),
 			       (unsigned long)(walk - inmap) +
-			       ntohl(header->offset));
+			       ntohl(header->offset), 
+				ntohl(header->loadaddress), ntohl(header->entry));
 		} else {
 			printf("(%d bytes, %s compressed to %d bytes "
-			       "@0x%lx)\n",
+			       "@0x%lx load @%#x, entry %#x)\n",
 			       ntohl(header->reallen),
 			       algo_name[ntohl(header->compression)],
 			       ntohl(header->len),
 			       (unsigned long)(walk - inmap) +
-			       ntohl(header->offset));
+			       ntohl(header->offset),
+				ntohl(header->loadaddress), ntohl(header->entry));
 		}
-
+		
 		walk += (ntohl(header->len) + ntohl(header->offset)
 			 - 1) & 0xfffffff0;
 	}
Index: util/lar/Makefile
===================================================================
--- util/lar/Makefile	(revision 464)
+++ util/lar/Makefile	(working copy)
@@ -17,7 +17,8 @@
 ## along with this program; if not, write to the Free Software
 ## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
 ##
-
+CFLAGS+= -g 
+LDFLAGS += -g
 LAROBJ := lar.o create.o extract.o list.o lib.o bootblock.o
 
 LARDIR := lardir
@@ -33,14 +34,15 @@
 endif
 
 LAROBJ_ABS := $(patsubst %,$(obj)/util/lar/%,$(LAROBJ))
-
+HOSTCFLAGS+=-g
+HOSTCXXFLAGS+=-g
 lardir:
 	$(Q)printf "  BUILD   LAR\n"
 	$(Q)mkdir -p $(obj)/util/lar
 
 $(obj)/util/lar/lar: $(LARDIR) $(LAROBJ_ABS) $(COMPRESSOR)
 	$(Q)printf "  HOSTCXX $(subst $(shell pwd)/,,$(@))\n"
-	$(Q)$(HOSTCXX) $(HOSTCXXFLAGS) -o $@ $(LAROBJ_ABS) $(COMPRESSOR)
+	$(Q)$(HOSTCXX) $(HOSTCXXFLAGS)  -o $@ $(LAROBJ_ABS) $(COMPRESSOR)
 
 $(obj)/util/lar/%.o: $(src)/util/lar/%.c
 	$(Q)printf "  HOSTCC  $(subst $(shell pwd)/,,$(@))\n"
