/*
 * Parse 32-bit ELF files.
 * Copyright (c) 2004 Russ Cox.  See LICENSE.
 */

#include <u.h>
#include <libc.h>
#include <mach.h>
#include "elf.h"

typedef struct ElfHdrBytes ElfHdrBytes;
typedef struct ElfSectBytes ElfSectBytes;
typedef struct ElfProgBytes ElfProgBytes;
typedef struct ElfSymBytes ElfSymBytes;

struct ElfHdrBytes
{
	uchar	ident[16];
	uchar	type[2];
	uchar	machine[2];
	uchar	version[4];
	uchar	entry[4];
	uchar	phoff[4];
	uchar	shoff[4];
	uchar	flags[4];
	uchar	ehsize[2];
	uchar	phentsize[2];
	uchar	phnum[2];
	uchar	shentsize[2];
	uchar	shnum[2];
	uchar	shstrndx[2];
};

struct ElfSectBytes
{
	uchar	name[4];
	uchar	type[4];
	uchar	flags[4];
	uchar	addr[4];
	uchar	offset[4];
	uchar	size[4];
	uchar	link[4];
	uchar	info[4];
	uchar	align[4];
	uchar	entsize[4];
};

struct ElfSymBytes
{
	uchar	name[4];
	uchar	value[4];
	uchar	size[4];
	uchar	info;	/* top4: bind, bottom4: type */
	uchar	other;
	uchar	shndx[2];
};

struct ElfProgBytes
{
	uchar	type[4];
	uchar	offset[4];
	uchar	vaddr[4];
	uchar	paddr[4];
	uchar	filesz[4];
	uchar	memsz[4];
	uchar	flags[4];
	uchar	align[4];
};

uchar ElfMagic[4] = { 0x7F, 'E', 'L', 'F' };

static void	unpackhdr(ElfHdr*, ElfHdrBytes*);
static void	unpackprog(ElfHdr*, ElfProg*, ElfProgBytes*);
static void	unpacksect(ElfHdr*, ElfSect*, ElfSectBytes*);

static char *elftypes[] = {
	"none",
	"relocatable",
	"executable",
	"shared object",
	"core",
};

char*
elftype(int t)
{
	if(t < 0 || t >= nelem(elftypes))
		return "unknown";
	return elftypes[t];
}

static char *elfmachs[] = {
	"none",
	"32100",
	"sparc",
	"386",
	"68000",
	"88000",
	"486",
	"860",
	"MIPS",
};

char*
elfmachine(int t)
{
	if(t < 0 || t >= nelem(elfmachs))
		return "unknown";
	return elfmachs[t];
}

Elf*
elfopen(char *name)
{
	int fd;
	Elf *e;

	if((fd = open(name, OREAD)) < 0)
		return nil;
	if((e = elfinit(fd)) == nil)
		close(fd);
	return e;
}

Elf*
elfinit(int fd)
{
	int i;
	Elf *e;
	ElfHdr *h;
	ElfHdrBytes hdrb;
	ElfProgBytes progb;
	ElfSectBytes sectb;
	ElfSect *s;

	e = mallocz(sizeof(Elf), 1);
	if(e == nil)
		return nil;
	e->fd = fd;

	/*
	 * parse header
	 */
	seek(fd, 0, 0);
	if(readn(fd, &hdrb, sizeof hdrb) != sizeof hdrb)
		goto err;
	h = &e->hdr;
	unpackhdr(h, &hdrb);
	if(h->class != ElfClass32){
		werrstr("bad ELF class - not 32-bit");
		goto err;
	}
	if(h->encoding != ElfDataLsb && h->encoding != ElfDataMsb){
		werrstr("bad ELF encoding - not LSB, MSB");
		goto err;
	}
	if(hdrb.ident[6] != h->version){
		werrstr("bad ELF encoding - version mismatch %02ux and %08ux",
			(uint)hdrb.ident[6], (uint)h->version);
		goto err;
	}

	/*
	 * the prog+section info is almost always small - just load it into memory.
	 */
	e->nprog = h->phnum;
	e->prog = mallocz(sizeof(ElfProg)*e->nprog, 1);
	for(i=0; i<e->nprog; i++){
		if(seek(fd, h->phoff+i*h->phentsize, 0) < 0
		|| readn(fd, &progb, sizeof progb) != sizeof progb)
			goto err;
		unpackprog(h, &e->prog[i], &progb);
	}

	e->nsect = h->shnum;
	if(e->nsect == 0)
		goto nosects;
	e->sect = mallocz(sizeof(ElfSect)*e->nsect, 1);
	for(i=0; i<e->nsect; i++){
		if(seek(fd, h->shoff+i*h->shentsize, 0) < 0
		|| readn(fd, &sectb, sizeof sectb) != sizeof sectb)
			goto err;
		unpacksect(h, &e->sect[i], &sectb);
	}

	if(h->shstrndx >= e->nsect){
		fprint(2, "warning: bad string section index %d >= %d", h->shstrndx, e->nsect);
		h->shnum = 0;
		e->nsect = 0;
		goto nosects;
	}
	s = &e->sect[h->shstrndx];
	if(elfmap(e, s) < 0)
		goto err;

	for(i=0; i<e->nsect; i++)
		if(e->sect[i].name)
			e->sect[i].name = s->base + (ulong)e->sect[i].name;

	e->symtab = elfsection(e, ".symtab");
	if(e->symtab){
		if(e->symtab->link >= e->nsect)
			e->symtab = nil;
		else{
			e->symstr = &e->sect[e->symtab->link];
			e->nsymtab = e->symtab->size / sizeof(ElfSymBytes);
		}
	}
	e->dynsym = elfsection(e, ".dynsym");
	if(e->dynsym){
		if(e->dynsym->link >= e->nsect)
			e->dynsym = nil;
		else{
			e->dynstr = &e->sect[e->dynsym->link];
			e->ndynsym = e->dynsym->size / sizeof(ElfSymBytes);
		}
	}

	e->bss = elfsection(e, ".bss");

nosects:
	return e;

err:
	free(e->sect);
	free(e->prog);
	free(e->shstrtab);
	free(e);
	return nil;
}

void
elfclose(Elf *elf)
{
	int i;

	for(i=0; i<elf->nsect; i++)
		free(elf->sect[i].base);
	free(elf->sect);
	free(elf->prog);
	free(elf->shstrtab);
	free(elf);
}

static void
unpackhdr(ElfHdr *h, ElfHdrBytes *b)
{
	u16int (*e2)(uchar*);
	u32int (*e4)(uchar*);
	u64int (*e8)(uchar*);

	memmove(h->magic, b->ident, 4);
	h->class = b->ident[4];
	h->encoding = b->ident[5];
	switch(h->encoding){
	case ElfDataLsb:
		e2 = leload2;
		e4 = leload4;
		e8 = leload8;
		break;
	case ElfDataMsb:
		e2 = beload2;
		e4 = beload4;
		e8 = beload8;
		break;
	default:
		return;
	}
	h->abi = b->ident[7];
	h->abiversion = b->ident[8];

	h->e2 = e2;
	h->e4 = e4;
	h->e8 = e8;
	
	h->type = e2(b->type);
	h->machine = e2(b->machine);
	h->version = e4(b->version);
	h->entry = e4(b->entry);
	h->phoff = e4(b->phoff);
	h->shoff = e4(b->shoff);
	h->flags = e4(b->flags);
	h->ehsize = e2(b->ehsize);
	h->phentsize = e2(b->phentsize);
	h->phnum = e2(b->phnum);
	h->shentsize = e2(b->shentsize);
	h->shnum = e2(b->shnum);
	h->shstrndx = e2(b->shstrndx);
}

static void
unpackprog(ElfHdr *h, ElfProg *p, ElfProgBytes *b)
{
	u32int (*e4)(uchar*);

	e4 = h->e4;
	p->type = e4(b->type);
	p->offset = e4(b->offset);
	p->vaddr = e4(b->vaddr);
	p->paddr = e4(b->paddr);
	p->filesz = e4(b->filesz);
	p->memsz = e4(b->memsz);
	p->flags = e4(b->flags);
	p->align = e4(b->align);
}

static void
unpacksect(ElfHdr *h, ElfSect *s, ElfSectBytes *b)
{
	u32int (*e4)(uchar*);

	e4 = h->e4;
	s->name = (char*)e4(b->name);
	s->type = e4(b->type);
	s->flags = e4(b->flags);
	s->addr = e4(b->addr);
	s->offset = e4(b->offset);
	s->size = e4(b->size);
	s->link = e4(b->link);
	s->info = e4(b->info);
	s->align = e4(b->align);
	s->entsize = e4(b->entsize);
}

ElfSect*
elfsection(Elf *elf, char *name)
{
	int i;

	for(i=0; i<elf->nsect; i++){
		if(elf->sect[i].name == name)
			return &elf->sect[i];
		if(elf->sect[i].name && name
		&& strcmp(elf->sect[i].name, name) == 0)
			return &elf->sect[i];
	}
	werrstr("elf section '%s' not found", name);
	return nil;
}

int
elfmap(Elf *elf, ElfSect *sect)
{
	if(sect->base)
		return 0;
	if((sect->base = malloc(sect->size)) == nil)
		return -1;
	werrstr("short read");
	if(seek(elf->fd, sect->offset, 0) < 0
	|| readn(elf->fd, sect->base, sect->size) != sect->size){
		free(sect->base);
		sect->base = nil;
		return -1;
	}
	return 0;
}

int
elfsym(Elf *elf, int i, ElfSym *sym)
{
	ElfSect *symtab, *strtab;
	uchar *p;
	char *s;
	ulong x;

	if(i < 0){
		werrstr("bad index %d in elfsym", i);
		return -1;
	}

	if(i < elf->nsymtab){
		symtab = elf->symtab;
		strtab = elf->symstr;
	extract:
		if(elfmap(elf, symtab) < 0 || elfmap(elf, strtab) < 0)
			return -1;
		p = symtab->base + i * sizeof(ElfSymBytes);
		s = strtab->base;
		x = elf->hdr.e4(p);
		if(x >= strtab->size){
			werrstr("bad symbol name offset 0x%lux", x);
			return -1;
		}
		sym->name = s + x;
		sym->value = elf->hdr.e4(p+4);
		sym->size = elf->hdr.e4(p+8);
		x = p[12];
		sym->bind = x>>4;
		sym->type = x & 0xF;
		sym->other = p[13];
		sym->shndx = elf->hdr.e2(p+14);
		return 0;
	}
	i -= elf->nsymtab;
	if(i < elf->ndynsym){
		symtab = elf->dynsym;
		strtab = elf->dynstr;
		goto extract;
	}
	/* i -= elf->ndynsym */

	werrstr("symbol index out of range");
	return -1;
}

