[prev in list] [next in list] [prev in thread] [next in thread] 

List:       uclinux
Subject:    [UCLINUX] loader for comressed file
From:       "Vadim Lebedev" <vlebedev () aplio ! fr>
Date:       2000-08-11 14:59:00
[Download RAW message or body]

Hi

For the people not using XIP (execute in place) functionality of ucLinux
i'm attaching a new version of binfmt_flat.c which
is able to load flat binaries compressed with flatzip
uitlity (also attcahed).  

binfmt_flat.c c goes in fs
flat.h goes into AplioTRIO/linux/include/asm and AplioTRIO/tools/elf2flt
fltzip.c goes into AplioTRIO/tools/elf2flt

Enjoy 
-----------------------------------------
Vadim Lebedev
Chief Software Engineer
Aplio SA.
mail:vlebedev@aplio.fr
http://www.aplio.com
------------------------------------------ 
["binfmt_flat.c" (application/octet-stream)]

/*
 *  linux/fs/binfmt_flat.c
 *
 *  Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>
 *                      The Silver Hammer Group, Ltd.
 *
 *  Splitted code/data memory allocations
 *  Added possibility to have compressed code/data
 *                      August 2000
 *                      Xavier Bestel <xbestel@aplio.fr>
 *
 *  This is a relatively simple binary format, intended solely to contain
 *  the bare minimum needed to load and execute simple binaries, with
 *  special attention to executing from ROM, when possible.
 *
 *  Originally based on:
 *
 *  linux/fs/binfmt_aout.c
 *
 *  Copyright (C) 1991, 1992, 1996  Linus Torvalds
 */
 

#include <linux/module.h>

#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/mman.h>
#include <linux/a.out.h>
#include <linux/errno.h>
#include <linux/signal.h>
#include <linux/string.h>
#include <linux/stat.h>
#include <linux/fcntl.h>
#include <linux/ptrace.h>
#include <linux/user.h>
#include <linux/malloc.h>
#include <linux/binfmts.h>
#include <linux/personality.h>

#include <asm/system.h>
#include <asm/segment.h>
#include <asm/pgtable.h>
#include <asm/flat.h>


#include <asm/byteorder.h>


//#define DEBUG

static int load_flat_binary(struct linux_binprm *, struct pt_regs * regs);

extern void dump_thread(struct pt_regs *, struct user *);

static struct linux_binfmt flat_format = {
#ifndef MODULE
	NULL, NULL, load_flat_binary, NULL, NULL
#else
	NULL, &mod_use_count_, load_flat_binary, NULL, NULL
#endif
};

static unsigned long putstring(unsigned long p, char * string)
{
	unsigned long l = strlen(string)+1;
#ifdef DEBUG
	printk("put_string '%s'\n", string);
#endif
	p -= l;
	memcpy((void*)p, string, l);
	return p;
}

static unsigned long putstringarray(unsigned long p, int count, char ** array)
{
	/*p=putstring(p, "");*/
	/*printk("p1=%x, array=%x\n", p, array);
	printk("array[0]=%x\n", array[0]);*/
#ifdef DEBUG
	printk("putstringarray(%d)\n", count);
#endif
	while(count) {
		p=putstring(p, array[--count]);
#ifdef DEBUG
		printk("p2=%x\n", (unsigned int)p);
#endif
	}
	return p;
}

static unsigned long stringarraylen(int count, char ** array)
{
	int l = 4;
	while(count) {
		l += strlen(array[--count]);
		l++;
		l+=4;
	}
	return l;
}

/* here are the zlib hacks - to replace globals with locals */

typedef unsigned char  uch;
typedef unsigned short ush;
typedef unsigned long  ulg;
#define INBUFSIZ 4096
#define WSIZE 0x8000    /* window size--must be a power of two, and */
                        /*  at least 32K for zip's deflate method */
struct s_zloc
{
	struct inode *inode;
	unsigned long start_pos;
	unsigned long bytes2read;
	char *data_pointer, *out_pointer;
	uch *inbuf;
	uch *window;
	unsigned insize;  /* valid bytes in inbuf */
	unsigned inptr;   /* index of next byte to be processed in inbuf */
	unsigned outcnt;  /* bytes in output buffer */
	int exit_code;
	long bytes_out;
	int crd_infp, crd_outfp;
	ulg bb;                         /* bit buffer */
	unsigned bk;                    /* bits in bit buffer */
	ulg crc_32_tab[256];
	ulg crc; /* shift register contents */
};

static int fill_inbuf(struct s_zloc *zloc)
{
	int i;
	if(zloc->exit_code)
		return -1;
	i = (zloc->bytes2read > INBUFSIZ) ? INBUFSIZ : zloc->bytes2read;
	if((i = read_exec(zloc->inode, zloc->start_pos, zloc->data_pointer, i, 0)) >= \
(unsigned long)-4096)  return -1;
	zloc->bytes2read -= i;
	zloc->start_pos += i;
	zloc->insize = i;
	zloc->inptr = 1;
	return zloc->inbuf[0];
}

static void flush_window(struct s_zloc *zloc)
{
	ulg c = zloc->crc;
	unsigned n;
	uch *in, ch;
	memcpy(zloc->out_pointer, zloc->window, zloc->outcnt);
	in = zloc->window;
	for(n = 0; n < zloc->outcnt; n++)
	{
		ch = *in++;
		c = zloc->crc_32_tab[((int)c ^ch) & 0xff] ^(c >> 8);
	}
	zloc->crc = c;
	zloc->out_pointer += zloc->outcnt;
	zloc->bytes_out += (ulg)zloc->outcnt;
	zloc->outcnt = 0;
}

#define inbuf (zloc->inbuf)
#define window (zloc->window)
#define insize (zloc->insize)
#define inptr (zloc->inptr)
#define outcnt (zloc->outcnt)
#define exit_code (zloc->exit_code)
#define bytes_out (zloc->bytes_out)
#define crd_infp (zloc->crd_infp)
#define crd_infp (zloc->crd_infp)
#define bb (zloc->bb)
#define bk (zloc->bk)
#define crc (zloc->crc)
#define crc_32_tab (zloc->crc_32_tab)

#define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf(zloc))
#define memzero(s, n)     memset ((s), 0, (n))

#define OF(args)  args
#define Assert(cond,msg)
#define Trace(x)
#define Tracev(x)
#define Tracevv(x)
#define Tracec(c,x)
#define Tracecv(c,x)

#define STATIC static

#define malloc(arg) kmalloc(arg, GFP_KERNEL)
#define free(arg) kfree(arg)

#define error(arg) printk("zflat:" arg "\n")

#include "../lib/inflate2.c"

#undef error

#undef malloc
#undef free

#undef inbuf
#undef window
#undef insize
#undef inptr
#undef outcnt
#undef exit_code
#undef bytes_out
#undef crd_infp
#undef crd_outp
#undef bb
#undef bk
#undef crc
#undef crc_32_tab

#undef get_byte
#undef memzero


static int decompress_exec(struct inode *inode, unsigned long offset, char * buffer, \
long len, int fd) {
	struct s_zloc *zloc;
	int res;
	zloc = kmalloc(sizeof(*zloc), GFP_KERNEL);
	if(!zloc)
	{
		return -ENOMEM;
	}
	memset(zloc, 0, sizeof(*zloc));
	zloc->inode = inode;
	zloc->out_pointer = buffer;
	zloc->inbuf = kmalloc(INBUFSIZ, GFP_KERNEL);
	if(!zloc->inbuf)
	{
		kfree(zloc);
		return -ENOMEM;
	}
	zloc->window = kmalloc(WSIZE, GFP_KERNEL);
	if(!zloc->window)
	{
		kfree(zloc->inbuf);
		kfree(zloc);
		return -ENOMEM;
	}
	zloc->data_pointer = zloc->inbuf;
	zloc->bytes2read = len;
	zloc->start_pos = offset;
	zloc->crc = (ulg)0xffffffffL;
	makecrc(zloc);
	res = gunzip(zloc);
	kfree(zloc->window);
	kfree(zloc->inbuf);
	kfree(zloc);
	return res ? -ENOMEM : 0;
}

/*
 * create_flat_tables() parses the env- and arg-strings in new user
 * memory and creates the pointer tables from them, and puts their
 * addresses on the "stack", returning the new stack pointer value.
 */
static unsigned long create_flat_tables(unsigned long pp, struct linux_binprm * bprm)
{
	unsigned long *argv,*envp;
	unsigned long * sp;
	char * p = (char*)pp;
	int argc = bprm->argc;
	int envc = bprm->envc;

	sp = (unsigned long *) ((-(unsigned long)sizeof(char *)) & (unsigned long) p);
#ifdef __alpha__
/* whee.. test-programs are so much fun. */
	put_user(0, --sp);
	put_user(0, --sp);
	if (bprm->loader) {
		put_user(0, --sp);
		put_user(0x3eb, --sp);
		put_user(bprm->loader, --sp);
		put_user(0x3ea, --sp);
	}
	put_user(bprm->exec, --sp);
	put_user(0x3e9, --sp);
#endif
	sp -= envc+1;
	envp = sp;
	sp -= argc+1;
	argv = sp;
#if defined(__i386__) || defined(__mc68000__) || defined(__arm__)
	put_user(envp,--sp);
	put_user(argv,--sp);
#endif
	put_user(argc,--sp);
	current->mm->arg_start = (unsigned long) p;
	while (argc-->0) {
		put_user(p,argv++);
		while (get_user(p++)) /* nothing */ ;
	}
	put_user(NULL,argv);
	current->mm->arg_end = current->mm->env_start = (unsigned long) p;
	while (envc-->0) {
		put_user(p,envp++);
		while (get_user(p++)) /* nothing */ ;
	}
	put_user(NULL,envp);
	current->mm->env_end = (unsigned long) p;
	return (unsigned long)sp;
}

void do_reloc(struct flat_reloc * r)
{
#ifdef DEBUG
	char *segment[] = { "TEXT", "DATA", "BSS", "*UNKNOWN*" };
#endif
	unsigned long * ptr = (unsigned long*)
		(current->mm->start_data + r->offset);

#ifdef DEBUG
	printk("Relocation of variable at DATASEG+%x (address %p, currently %x) into segment \
%s\n",  r->offset, ptr, (int)*ptr, segment[r->type]);
#endif
	
	switch (r->type) {
	case FLAT_RELOC_TYPE_TEXT:
		*ptr += current->mm->start_code;
		break;
	case FLAT_RELOC_TYPE_DATA:
		*ptr += current->mm->start_data;
		break;
	case FLAT_RELOC_TYPE_BSS:
		*ptr += current->mm->end_data;
		break;
	default:
		printk("ERROR: Unknown relocation\n");
	}

 
#ifdef DEBUG
	printk("Relocation became %x\n", (int)*ptr);
#endif
}		


/*
 * These are the functions used to load (z)flat style executables and shared
 * libraries.  There is no binary dependent code anywhere else.
 */

#warning ********************************************
#warning *                                          *
#warning * binfmt_flat.c is currently *broken*      *
#warning * because is has unlocked global variables *
#warning *                                          *
#warning * so what ? so this is a test release only *
#warning * and it works ? maybe, if ur lucky enough *
#warning *                                          *
#warning ********************************************

inline int
do_load_flat_binary(struct linux_binprm * bprm, struct pt_regs * regs)
{
	struct flat_hdr * hdr;
	struct file * file;
	unsigned long result;
	unsigned long pos_code, pos_data, pos_bss, pos_stack;
	unsigned long p = bprm->p;
	unsigned long data_len, bss_len, stack_len, code_len;
	unsigned long fildatst;


	current->personality = PER_LINUX;
	
	file = current->files->fd[open_inode(bprm->inode, O_RDONLY)];
	
#ifdef DEBUG
	printk("BINFMT_FLAT: Loading file: %x\n", (int)file);
	show_free_areas();
#endif

	hdr = (struct flat_hdr*)bprm->buf;
	
	if (strncmp(hdr->magic, "bFLT", 4) || ((hdr->rev != ntohl(2)) && (hdr->rev != \
ntohl(3)))) {  printk("bad magic/rev (%ld, need %d or %d)\n", ntohl(hdr->rev), 2, 3);
		return -ENOEXEC;
	}

	if (flush_old_exec(bprm)) {
		printk("unable to flush\n");
		return -ENOMEM;
	}
	
	code_len = ntohl(hdr->data_start) - ntohl(hdr->entry);
	data_len = ntohl(hdr->data_end) - code_len;
	bss_len = ntohl(hdr->bss_end) - ntohl(hdr->data_end);
	stack_len = ntohl(hdr->stack_size);
	
	/* Make room on stack for arguments & environment */
	stack_len += strlen(bprm->filename) + 1;
	stack_len += stringarraylen(bprm->envc, bprm->envp);
	stack_len += stringarraylen(bprm->argc, bprm->argv);
	
	// allocate separate chunks of mem - one day I should
	// make a smart allocator which groups small chunks
	if((pos_code = do_mmap(0, 0, code_len, PROT_READ|PROT_WRITE|PROT_EXEC, 0, 0)) >= \
(unsigned long)-4096)  return pos_code;
	if((pos_data = do_mmap(0, 0, data_len + bss_len, PROT_READ|PROT_WRITE|PROT_EXEC, 0, \
0)) >= (unsigned long)-4096)  {
		do_munmap(pos_code, 0);
		return pos_data;
	}
	pos_bss = pos_data + data_len;
	if((pos_stack = do_mmap(0, 0, stack_len, PROT_READ|PROT_WRITE|PROT_EXEC, 0, 0)) >= \
(unsigned long)-4096)  {
		do_munmap(pos_code, 0);
		do_munmap(pos_data, 0);
		return pos_stack;
	}
#ifdef DEBUG
	printk("BINFMT_FLAT: \
Allocated:\ncode\t0x%x\tOx%x\ndata\t0x%x\tOx%x\nbss\t0x%x\tOx%x\nstack\t0x%x\tOx%x\n", \
(int)pos_code, (int)code_len, (int)pos_data, (int)data_len, (int)pos_bss, \
(int)bss_len, (int)pos_stack, (int)stack_len);  show_free_areas();
#endif
	// read code and data in memory
	result = (hdr->flags & FLAT_GZIP_CODE) ? decompress_exec(bprm->inode, \
ntohl(hdr->entry), (char *)pos_code, ntohl(hdr->gz_codesize), 0) : \
read_exec(bprm->inode, ntohl(hdr->entry), (char *)pos_code, code_len, 0);  if(result \
>= (unsigned long)-4096)  {
		do_munmap(pos_code, 0);
		do_munmap(pos_data, 0);
		do_munmap(pos_stack, 0);
		return result;
	}
	fildatst = (hdr->flags & FLAT_GZIP_CODE) ? ntohl(hdr->entry) + \
ntohl(hdr->gz_codesize) : ntohl(hdr->data_start);  result = (hdr->flags & \
FLAT_GZIP_DATA) ? decompress_exec(bprm->inode, fildatst, (char *)pos_data, data_len, \
0) : read_exec(bprm->inode, fildatst, (char *)pos_data, data_len, 0);  if(result >= \
(unsigned long)-4096)  {
		do_munmap(pos_code, 0);
		do_munmap(pos_data, 0);
		do_munmap(pos_stack, 0);
		return result;
	}
	memset((void*)pos_bss, 0, bss_len);
	memset((void*)pos_stack, 0, stack_len);

	current->mm->start_code = pos_code;
	current->mm->end_code = pos_code + code_len;
	current->mm->start_data = pos_data;
	current->mm->end_data = pos_data + data_len;
	current->mm->brk = pos_bss + bss_len;
	if (bprm->inode->i_sb->s_flags & MS_SYNCHRONOUS) {
#ifdef DEBUG
		printk("Retaining inode\n");
#endif
		current->mm->executable = bprm->inode;
		bprm->inode->i_count++;
	}
	else
		current->mm->executable = 0;
	
	printk("Loaded flat file, BSS=%x, DATA=%x, TEXT=%x\n",
		(int)current->mm->end_data,
		(int)current->mm->start_data,
		(int)current->mm->start_code);

	{
		int r;
		int rcnt = ntohl(hdr->reloc_count);

		for(r=0;r<rcnt;r++) {
			union {
				struct flat_reloc reloc;
				unsigned long lword;
			} rr;
			unsigned long result = read_exec(bprm->inode, 
				ntohl(hdr->reloc_start) + (sizeof(struct flat_reloc)*r), 
				(char *)&rr,
			  	sizeof(struct flat_reloc), 
			  	0);
			if (result >= (unsigned long)-4096) {
				printk("Failure reloading relocation\n");
			}
			else
			{
				rr.lword = ntohl(rr.lword);
				do_reloc(&rr.reloc);
			}
		}
	}

	current->mm->rss = 0;
	current->suid = current->euid = current->fsuid = bprm->e_uid;
	current->sgid = current->egid = current->fsgid = bprm->e_gid;
 	current->flags &= ~PF_FORKNOEXEC;
 	
 	
        
	if (current->exec_domain && current->exec_domain->use_count)
		(*current->exec_domain->use_count)--;
	if (current->binfmt && current->binfmt->use_count)
		(*current->binfmt->use_count)--;
	current->exec_domain = lookup_exec_domain(current->personality);
	current->binfmt = &flat_format;
	if (current->exec_domain && current->exec_domain->use_count)
		(*current->exec_domain->use_count)++;
	if (current->binfmt && current->binfmt->use_count)
		(*current->binfmt->use_count)++;

	/*set_brk(current->mm->start_brk, current->mm->brk);*/

	p = pos_stack + stack_len - 4;
	
#ifdef DEBUG
	printk("p=%x\n", (int)p);
#endif
	
	p = putstringarray(p, 1, &bprm->filename);

#ifdef DEBUG
	printk("p(filename)=%x\n", (int)p);
#endif

	p = putstringarray(p, bprm->envc, bprm->envp);

#ifdef DEBUG
	printk("p(envp)=%x\n", (int)p);
#endif

	p = putstringarray(p, bprm->argc, bprm->argv);

#ifdef DEBUG
	printk("p(argv)=%x\n", (int)p);
#endif

	p = create_flat_tables(p, bprm);

#ifdef DEBUG
	printk("p(create_flat_tables)=%x\n", (int)p);
	
	printk("arg_start = %x\n", (int)current->mm->arg_start);
	printk("arg_end = %x\n", (int)current->mm->arg_end);
	printk("env_start = %x\n", (int)current->mm->env_start);
	printk("env_end = %x\n", (int)current->mm->env_end);
#endif

	current->mm->start_stack = p;

	/*printk("start_stack: %x\n", current->mm->start_stack);*/
	
	/*(*(volatile unsigned char *)0xdeadbee0) = 1;*/

#ifdef DEBUG	
	show_free_areas();
#endif

	start_thread(regs, current->mm->start_code, current->mm->start_data /*- \
hdr->data_start*/, p);  
	if (current->flags & PF_PTRACED)
		send_sig(SIGTRAP, current, 0);
	return 0;
}

static int
load_flat_binary(struct linux_binprm * bprm, struct pt_regs * regs)
{
	int retval;

	MOD_INC_USE_COUNT;
	retval = do_load_flat_binary(bprm, regs);
	MOD_DEC_USE_COUNT;
	return retval;
}

int init_flat_binfmt(void) {
	return register_binfmt(&flat_format);
}

#ifdef MODULE
int init_module(void) {
	return init_flat_binfmt();
}

void cleanup_module( void) {
	unregister_binfmt(&flat_format);
}
#endif


["flat.h" (application/octet-stream)]
["fltzip.c" (application/octet-stream)]

/*

flat binary dumper, zipper and dezipper
xavier bestel <xbestel@aplio.fr> 1999

*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <zlib.h>
#include "flat.h"

static char *rtype[]={ "text", "data", "bss", "??!?" };

inline void* smalloc(size_t len)
{
	void *p=malloc(len);
	if(!p)
	{
		fprintf(stderr, "error ! malloc() failed\n");
		exit(1);
	}
	return p;
}

inline void* scalloc(int n, size_t len)
{
	void *p=calloc(n, len);
	if(!p)
	{
		fprintf(stderr, "error ! calloc() failed\n");
		exit(1);
	}
	return p;
}

#define malloc smalloc
#define calloc scalloc

int my_compress(char *zbuf, int *zlen, char *buf, int len)
{
	char fn[20], zfn[20], gs[30];
	FILE *fh;
	sprintf(fn, "/tmp/zflat%d", getpid());
	sprintf(zfn, "/tmp/zflat%d.gz", getpid());
	sprintf(gs, "gzip -n -9 %s", fn);
	fh = fopen(fn, "w");
	fwrite(buf, 1, len, fh);
	fclose(fh);
	system(gs);
	fh = fopen(zfn, "r");
	*zlen = fread(zbuf, 1, *zlen, fh);
	fclose(fh);
	unlink(fn);
	unlink(zfn);
	return 0;
}

int main(int argc, char *argv[])
{
	FILE *fh, *fh2, *fh3;
	struct flat_hdr flat;
	char *p_code, *p_data;
	char *z_code, *z_data;
	unsigned long *p_relocs;
	int i, n_relocs, reloc_start;
	int code_start, data_start, data_end, bss_end;
	int code_len, data_len;

	if(argc < 2)
	{
		printf("usage: %s flat_binary [zipped_flat_binary] [unzipped_flat_binary]\n", \
argv[0]);  return 1;
	}
	if(!(fh = fopen(argv[1], "r")))
	{
		printf("couldn't open file %s\n", argv[1]);
		return 1;
	}
	fh2 = (argc > 2) ? fopen(argv[2], "w") : 0;
	fh3 = (argc > 3) ? fopen(argv[3], "w") : 0;
	fread(&flat, sizeof(flat), 1, fh);
	printf("flat.magic = \"%c%c%c%c\" revision %d\n", flat.magic[0], flat.magic[1], \
flat.magic[2], flat.magic[3], ntohl(flat.rev));  printf("entry = 0x%x\ndata_start = \
0x%x\ndata_end = 0x%x\nbss_end = 0x%x\nstack_size = 0x%x\n"  , code_start = \
ntohl(flat.entry), data_start = ntohl(flat.data_start), data_end = \
ntohl(flat.data_end), bss_end = ntohl(flat.bss_end), ntohl(flat.stack_size));  \
printf("%d relocs starting offset 0x%x\n", n_relocs = ntohl(flat.reloc_count), \
reloc_start = ntohl(flat.reloc_start));  
	code_len = data_start - code_start;
	data_len = data_end - data_start;

	p_code = malloc(code_len);
	p_data = malloc(data_len);
	p_relocs = calloc(n_relocs, sizeof(struct flat_reloc));
	if(flat.flags & FLAT_GZIP_CODE)
	{
		long len = code_len;
		z_code = malloc(ntohl(flat.gz_codesize));
		fread(z_code, ntohl(flat.gz_codesize), 1, fh);
		if(uncompress(p_code, &len, z_code, ntohl(flat.gz_codesize)) != Z_OK)
		{
			printf("error when decompressing code\n");
			exit(1);
		}
		if(len != code_len)
		{
			printf("short code decompression !\n");
			exit(1);
		}
		free(z_code);
		printf("unzipped code: %d => %d\n", ntohl(flat.gz_codesize), len);
	}
	else
		fread(p_code, code_len, 1, fh);
	if(flat.flags & FLAT_GZIP_DATA)
	{
		long len = data_len;
		z_data = malloc(ntohl(flat.gz_datasize));
		fread(z_data, ntohl(flat.gz_datasize), 1, fh);
		if(uncompress(p_data, &len, z_data, ntohl(flat.gz_datasize)) != Z_OK)
		{
			printf("error when decompressing data\n");
			exit(1);
		}
		if(len != data_len)
		{
			printf("short data decompression !\n");
			exit(1);
		}
		free(z_data);
		printf("unzipped data: %d => %d\n", ntohl(flat.gz_datasize), len);
	}
	else
		fread(p_data, data_len, 1, fh);
	fread(p_relocs, sizeof(struct flat_reloc), n_relocs, fh);
	if(!(fh2 || fh3))
		for(i=0; i<n_relocs; i++)
		{
			struct flat_reloc r;
			int fromtype;
			*((unsigned long *)&r) = ntohl(p_relocs[i]);
#if 0
			if (r.offset >=0 && r.offset < data_start)
				fromtype = 0;
			else if (r.offset >= data_start && r.offset < data_end)
#endif
				fromtype = 1;
#if 0
			else if (r.offset >= data_end && r.offset < bss_end)
				fromtype = 2;
			else
				fromtype = 3;
#endif
			printf("reloc to %4s segment at offset 0x%08x (in %4s segment)\n", rtype[r.type], \
r.offset, rtype[fromtype]);  }
	if(fh2)
	{
		long z_codelen = code_len * 1.1 + 12;
		long z_datalen = data_len * 1.1 + 12;
		z_code = malloc(z_codelen);
		z_data = malloc(z_datalen);
		if(my_compress(z_code, &z_codelen, p_code, code_len))
		{
			printf("couldn't compress code\n");
			return 1;
		}
		if(my_compress(z_data, &z_datalen, p_data, data_len))
		{
			printf("couldn't compress data\n");
			return 1;
		}
		printf("code: %d => %d\ndata: %d => %d\n", code_len, z_codelen, data_len, \
z_datalen);  flat.flags |= (FLAT_GZIP_CODE|FLAT_GZIP_DATA);
		flat.rev = htonl(3);
		flat.gz_codesize = htonl(z_codelen);
		flat.gz_datasize = htonl(z_datalen);
		flat.reloc_start = htonl(sizeof(flat) + z_codelen + z_datalen);
		fwrite(&flat, sizeof(flat), 1, fh2);
		fwrite(z_code, z_codelen, 1, fh2);
		fwrite(z_data, z_datalen, 1, fh2);
		fwrite(p_relocs, sizeof(struct flat_reloc), n_relocs, fh2);
		fclose(fh2);
	}
	if(fh3)
	{
		flat.flags &= ~(FLAT_GZIP_CODE|FLAT_GZIP_DATA);
		flat.rev = htonl(2);
		flat.gz_codesize = 0;
		flat.gz_datasize = 0;
		flat.reloc_start = htonl(ntohl(flat.entry) + code_len + data_len);
		fwrite(&flat, sizeof(flat), 1, fh3);
		fwrite(p_code, code_len, 1, fh3);
		fwrite(p_data, data_len, 1, fh3);
		fwrite(p_relocs, sizeof(struct flat_reloc), n_relocs, fh3);
		fclose(fh2);
	}
	return 0;
}



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic