view old/tmp/loadelf.cc @ 998:ad5232ad4952

add fb_test, minor fix
author yutaka@localhost.localdomain
date Fri, 15 Oct 2010 02:13:55 +0900
parents 49b3c753e209
children
line wrap: on
line source

/*
      load spu elf file into memory with proper alignment.
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <elf.h>
#include "types.h"
#include <alloca.h>
#include <malloc.h>
#include <strings.h>


static int
read_file(int fd, unsigned char *buf, int size)
{
    int i = 0;
    do {
        int j = read(fd,buf+i,size-i);
        if (j<0) return j;
        i+=j;
    } while( i< size ) ;
    return i;
}

static memaddr
load_elf1(int fd)
{
    Elf32_Ehdr header;

    if (read_file(fd, (unsigned char *)&header, sizeof(header))<0) return 0;

    if (header.e_ident[EI_CLASS]==ELFCLASS32) printf("32bit\n");
    printf("entry %0lx\n", (unsigned long)header.e_entry);
    printf("program header %0lx ", (unsigned long)header.e_phoff);
    printf("length %0lx\n", (unsigned long)header.e_phentsize);
    printf("section header %0lx ", (unsigned long)header.e_shoff);
    printf("length %0lx\n", (unsigned long)header.e_shentsize);
    printf("e_shstrndx %ld\n", (unsigned long)header.e_shstrndx);

    int num = header.e_shnum;
    Elf32_Shdr section[num] ;

    lseek(fd,header.e_shoff + (sizeof(Elf32_Shdr )*(header.e_shstrndx)),SEEK_SET);
    if (read_file(fd, (unsigned char *)&section[0], sizeof(Elf32_Shdr))<0) return 0;
    unsigned char *text = (unsigned char *)alloca(section[0].sh_size);
    lseek(fd,section[0].sh_offset,SEEK_SET);
    if (read_file(fd, text, section[0].sh_size)<0) return 0;
    // for(int i=0;i<section.sh_size;i++) putchar(text[i]);

    lseek(fd,header.e_shoff,SEEK_SET);
    if (read_file(fd, (unsigned char *)&section[0], sizeof(Elf32_Shdr)*num)<0) return 0;
    long min = 0x7fffffff;
    long max = 0;

    for(int i=0; i< num; i++) {
        if (section[i].sh_flags & SHF_ALLOC) {
             int adr = section[i].sh_addr;
             if (min>adr) min = adr;
             adr += section[i].sh_size ;
             if (max<adr) max = adr;
        }
        printf("section %d ",i) ;
        printf("  sh_name %s\n",text+section[i].sh_name) ;
        printf("  sh_name %lx ",(unsigned long)section[i].sh_name) ;
        printf("  sh_type %lx ",(unsigned long)section[i].sh_type) ;
        printf("  sh_addr %lx ",(unsigned long)section[i].sh_addr) ;
        printf("  sh_offset %lx ",(unsigned long)section[i].sh_offset) ;
        printf("  sh_size %lx\n",(unsigned long)section[i].sh_size) ;
    }
    printf("\nmax %lx min %lx\n",max,min) ;

#if 0
    unsigned  char  *code = (unsigned char*)malloc(max-min);
#else
    unsigned  char  *code ;
    posix_memalign((void**)&code,16,max-min);
#endif

    bzero(code,max-min);
    printf("bzero %lx\n", (unsigned long)code) ;

    long poffset = -1;    
    unsigned char *addr = code;
    unsigned long size  = 0;    
    for(int i=0; i< num; i++) {
        if ((section[i].sh_flags & SHF_ALLOC) && (section[i].sh_type!=SHT_NOBITS)) {
	    printf("loading %lx %lx\n", 
                   (unsigned long)(section[i].sh_addr), 
                   (unsigned long)section[i].sh_size) ;
            long offset = (unsigned long)(section[i].sh_addr-min)-
                  (unsigned long)section[i].sh_offset;
	    if (offset!=poffset) {
                if (addr && size) {
		    printf("   reading %lx %lx\n", 
			   (unsigned long)addr, 
			   (unsigned long)size) ;
		    if (read_file(fd, addr, size)<0) return 0;
                }
                 // there is a hole
                printf("   hole %0x = %0x - %0x\n", offset-poffset, offset, poffset);
                poffset = offset;
		lseek(fd,section[i].sh_offset,SEEK_SET);
	        addr = code + (section[i].sh_addr-min);
            } 
	    unsigned char *last = 
		 code + (section[i].sh_addr-min+section[i].sh_size);
	    size = last - addr;
        }
    }
    printf("   last reading %lx %lx\n", 
	   (unsigned long)addr, 
	   (unsigned long)size) ;
    if (read_file(fd, addr, size)<0) return 0;
    return (memaddr)code;
}

static memaddr
load_elf(const char *name)
{
    Elf32_Ehdr header;

    int fd = open(name,O_RDONLY);
    if (fd<0) return 0;
    memaddr addr = load_elf1(fd);
    close(fd);
    return addr;
}

int
main(int ac, char *av[])
{
    load_elf(av[1]);
    return 0;
}