// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Mach-O file writing
// http://developer.apple.com/mac/library/DOCUMENTATION/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html

#include "l.h"
#include "../ld/lib.h"
#include "../ld/macho.h"

static	int	macho64;
static	MachoHdr	hdr;
static	MachoLoad	load[16];
static	MachoSeg	seg[16];
static	MachoDebug	xdebug[16];
static	int	nload, nseg, ndebug, nsect;

void
machoinit(void)
{
	switch(thechar) {
	// 64-bit architectures
	case '6':
		macho64 = 1;
		break;

	// 32-bit architectures
	default:
		break;
	}
}

MachoHdr*
getMachoHdr(void)
{
	return &hdr;
}

MachoLoad*
newMachoLoad(uint32 type, uint32 ndata)
{
	MachoLoad *l;

	if(nload >= nelem(load)) {
		diag("too many loads");
		errorexit();
	}
	l = &load[nload++];
	l->type = type;
	l->ndata = ndata;
	l->data = mal(ndata*4);
	return l;
}

MachoSeg*
newMachoSeg(char *name, int msect)
{
	MachoSeg *s;

	if(nseg >= nelem(seg)) {
		diag("too many segs");
		errorexit();
	}
	s = &seg[nseg++];
	s->name = name;
	s->msect = msect;
	s->sect = mal(msect*sizeof s->sect[0]);
	return s;
}

MachoSect*
newMachoSect(MachoSeg *seg, char *name)
{
	MachoSect *s;

	if(seg->nsect >= seg->msect) {
		diag("too many sects in segment %s", seg->name);
		errorexit();
	}
	s = &seg->sect[seg->nsect++];
	s->name = name;
	nsect++;
	return s;
}

MachoDebug*
newMachoDebug(void)
{
	if(ndebug >= nelem(xdebug)) {
		diag("too many debugs");
		errorexit();
	}
	return &xdebug[ndebug++];
}


// Generic linking code.

static uchar *linkdata;
static uint32 nlinkdata;
static uint32 mlinkdata;

static uchar *strtab;
static uint32 nstrtab;
static uint32 mstrtab;

struct	Expsym
{
	int	off;
	Sym*	s;
} *expsym;
static int nexpsym;
static int nimpsym;

static char **dylib;
static int ndylib;

static vlong linkoff;

int
machowrite(void)
{
	vlong o1;
	int loadsize;
	int i, j;
	MachoSeg *s;
	MachoSect *t;
	MachoDebug *d;
	MachoLoad *l;

	o1 = Boffset(&bso);

	loadsize = 4*4*ndebug;
	for(i=0; i<nload; i++)
		loadsize += 4*(load[i].ndata+2);
	if(macho64) {
		loadsize += 18*4*nseg;
		loadsize += 20*4*nsect;
	} else {
		loadsize += 14*4*nseg;
		loadsize += 17*4*nsect;
	}

	if(macho64)
		LPUT(0xfeedfacf);
	else
		LPUT(0xfeedface);
	LPUT(hdr.cpu);
	LPUT(hdr.subcpu);
	LPUT(2);	/* file type - mach executable */
	LPUT(nload+nseg+ndebug);
	LPUT(loadsize);
	LPUT(1);	/* flags - no undefines */
	if(macho64)
		LPUT(0);	/* reserved */

	for(i=0; i<nseg; i++) {
		s = &seg[i];
		if(macho64) {
			LPUT(25);	/* segment 64 */
			LPUT(72+80*s->nsect);
			strnput(s->name, 16);
			VPUT(s->vaddr);
			VPUT(s->vsize);
			VPUT(s->fileoffset);
			VPUT(s->filesize);
			LPUT(s->prot1);
			LPUT(s->prot2);
			LPUT(s->nsect);
			LPUT(s->flag);
		} else {
			LPUT(1);	/* segment 32 */
			LPUT(56+68*s->nsect);
			strnput(s->name, 16);
			LPUT(s->vaddr);
			LPUT(s->vsize);
			LPUT(s->fileoffset);
			LPUT(s->filesize);
			LPUT(s->prot1);
			LPUT(s->prot2);
			LPUT(s->nsect);
			LPUT(s->flag);
		}
		for(j=0; j<s->nsect; j++) {
			t = &s->sect[j];
			if(macho64) {
				strnput(t->name, 16);
				strnput(s->name, 16);
				VPUT(t->addr);
				VPUT(t->size);
				LPUT(t->off);
				LPUT(t->align);
				LPUT(t->reloc);
				LPUT(t->nreloc);
				LPUT(t->flag);
				LPUT(0);	/* reserved */
				LPUT(0);	/* reserved */
				LPUT(0);	/* reserved */
			} else {
				strnput(t->name, 16);
				strnput(s->name, 16);
				LPUT(t->addr);
				LPUT(t->size);
				LPUT(t->off);
				LPUT(t->align);
				LPUT(t->reloc);
				LPUT(t->nreloc);
				LPUT(t->flag);
				LPUT(0);	/* reserved */
				LPUT(0);	/* reserved */
			}
		}
	}

	for(i=0; i<nload; i++) {
		l = &load[i];
		LPUT(l->type);
		LPUT(4*(l->ndata+2));
		for(j=0; j<l->ndata; j++)
			LPUT(l->data[j]);
	}

	for(i=0; i<ndebug; i++) {
		d = &xdebug[i];
		LPUT(3);	/* obsolete gdb debug info */
		LPUT(16);	/* size of symseg command */
		LPUT(d->fileoffset);
		LPUT(d->filesize);
	}

	return Boffset(&bso) - o1;
}

static void*
grow(uchar **dat, uint32 *ndat, uint32 *mdat, uint32 n)
{
	uchar *p;
	uint32 old;

	if(*ndat+n > *mdat) {
		old = *mdat;
		*mdat = (*ndat+n)*2 + 128;
		*dat = realloc(*dat, *mdat);
		if(*dat == 0) {
			diag("out of memory");
			errorexit();
		}
		memset(*dat+old, 0, *mdat-old);
	}
	p = *dat + *ndat;
	*ndat += n;
	return p;
}

static int
needlib(char *name)
{
	char *p;
	Sym *s;

	/* reuse hash code in symbol table */
	p = smprint(".machoload.%s", name);
	s = lookup(p, 0);
	if(s->type == 0) {
		s->type = 100;	// avoid SDATA, etc.
		return 1;
	}
	return 0;
}

void
domacho(void)
{
	int h, ptrsize, t;
	char *p;
	uchar *dat;
	uint32 x;
	Sym *s;
	Sym **impsym;

	ptrsize = 4;
	if(macho64)
		ptrsize = 8;

	// empirically, string table must begin with " \x00".
	if(!debug['d'])
		*(char*)grow(&strtab, &nstrtab, &mstrtab, 2) = ' ';

	impsym = nil;
	for(h=0; h<NHASH; h++) {
		for(s=hash[h]; s!=S; s=s->link) {
			if(!s->reachable || (s->type != STEXT && s->type != SDATA && s->type != SBSS) || s->dynimpname == nil)
				continue;
			if(debug['d']) {
				diag("cannot use dynamic loading and -d");
				errorexit();
			}
			if(!s->dynexport) {
				if(nimpsym%32 == 0) {
					impsym = realloc(impsym, (nimpsym+32)*sizeof impsym[0]);
					if(impsym == nil) {
						diag("out of memory");
						errorexit();
					}
				}
				impsym[nimpsym++] = s;
				continue;
			}

			/* symbol table entry - darwin still puts _ prefixes on all C symbols */
			x = nstrtab;
			p = grow(&strtab, &nstrtab, &mstrtab, 1+strlen(s->dynimpname)+1);
			*p++ = '_';
			strcpy(p, s->dynimpname);

			dat = grow(&linkdata, &nlinkdata, &mlinkdata, 8+ptrsize);
			dat[0] = x;
			dat[1] = x>>8;
			dat[2] = x>>16;
			dat[3] = x>>24;

			dat[4] = 0x0f;	// type: N_SECT | N_EXT - external, defined in sect
			switch(s->type) {
			default:
			case STEXT:
				t = 1;
				break;
			case SDATA:
				t = 2;
				break;
			case SBSS:
				t = 4;
				break;
			}
			dat[5] = t;	// sect: section number

			if (nexpsym%32 == 0) {
				expsym = realloc(expsym, (nexpsym+32)*sizeof expsym[0]);
				if (expsym == nil) {
					diag("out of memory");
					errorexit();
				}
			}
			expsym[nexpsym].off = nlinkdata - ptrsize;
			expsym[nexpsym++].s = s;
		}
	}

	for(h=0; h<nimpsym; h++) {
		s = impsym[h];
		s->type = SMACHO;
		s->value = (nexpsym+h) * ptrsize;

		/* symbol table entry - darwin still puts _ prefixes on all C symbols */
		x = nstrtab;
		p = grow(&strtab, &nstrtab, &mstrtab, 1+strlen(s->dynimpname)+1);
		*p++ = '_';
		strcpy(p, s->dynimpname);

		dat = grow(&linkdata, &nlinkdata, &mlinkdata, 8+ptrsize);
		dat[0] = x;
		dat[1] = x>>8;
		dat[2] = x>>16;
		dat[3] = x>>24;

		dat[4] = 0x01;	// type: N_EXT - external symbol

		if(needlib(s->dynimplib)) {
			if(ndylib%32 == 0) {
				dylib = realloc(dylib, (ndylib+32)*sizeof dylib[0]);
				if(dylib == nil) {
					diag("out of memory");
					errorexit();
				}
			}
			dylib[ndylib++] = s->dynimplib;
		}
	}
	free(impsym);

	/*
	 * list of symbol table indexes.
	 * we don't take advantage of the opportunity
	 * to order the symbol table differently from
	 * this list, so it is boring: 0 1 2 3 4 ...
	 */
	for(x=0; x<nexpsym+nimpsym; x++) {
		dat = grow(&linkdata, &nlinkdata, &mlinkdata, 4);
		dat[0] = x;
		dat[1] = x>>8;
		dat[2] = x>>16;
		dat[3] = x>>24;
	}

	dynptrsize = (nexpsym+nimpsym) * ptrsize;
}

vlong
domacholink(void)
{
	int i;
	uchar *p;
	Sym *s;
	uint64 val;

	linkoff = 0;
	if(nlinkdata > 0) {
		linkoff = rnd(HEADR+textsize, INITRND) + rnd(datsize, INITRND);
		seek(cout, linkoff, 0);

		for(i = 0; i<nexpsym; ++i) {
			s = expsym[i].s;
			val = s->value;
			if(s->type == SUNDEF)
				diag("export of undefined symbol %s", s->name);
			if (s->type != STEXT)
				val += INITDAT;
			p = linkdata+expsym[i].off;
			p[0] = val;
			p[1] = val >> 8;
			p[2] = val >> 16;
			p[3] = val >> 24;
			if (macho64) {
				p[4] = val >> 32;
				p[5] = val >> 40;
				p[6] = val >> 48;
				p[7] = val >> 56;
			}
		}

		write(cout, linkdata, nlinkdata);
		write(cout, strtab, nstrtab);
	}
	return rnd(nlinkdata+nstrtab, INITRND);
}

void
asmbmacho(vlong symdatva, vlong symo)
{
	vlong v, w;
	vlong va;
	int a, i, ptrsize;
	char *pkgroot;
	MachoHdr *mh;
	MachoSect *msect;
	MachoSeg *ms;
	MachoDebug *md;
	MachoLoad *ml;

	/* apple MACH */
	va = INITTEXT - HEADR;
	mh = getMachoHdr();
	switch(thechar){
	default:
		diag("unknown mach architecture");
		errorexit();
	case '6':
		mh->cpu = MACHO_CPU_AMD64;
		mh->subcpu = MACHO_SUBCPU_X86;
		ptrsize = 8;
		break;
	case '8':
		mh->cpu = MACHO_CPU_386;
		mh->subcpu = MACHO_SUBCPU_X86;
		ptrsize = 4;
		break;
	}

	/* segment for zero page */
	ms = newMachoSeg("__PAGEZERO", 0);
	ms->vsize = va;

	/* text */
	v = rnd(HEADR+textsize, INITRND);
	ms = newMachoSeg("__TEXT", 1);
	ms->vaddr = va;
	ms->vsize = v;
	ms->filesize = v;
	ms->prot1 = 7;
	ms->prot2 = 5;

	msect = newMachoSect(ms, "__text");
	msect->addr = INITTEXT;
	msect->size = textsize;
	msect->off = INITTEXT - va;
	msect->flag = 0x400;	/* flag - some instructions */

	/* data */
	w = datsize+dynptrsize+bsssize;
	ms = newMachoSeg("__DATA", 2+(dynptrsize>0));
	ms->vaddr = va+v;
	ms->vsize = w;
	ms->fileoffset = v;
	ms->filesize = datsize;
	ms->prot1 = 7;
	ms->prot2 = 3;

	msect = newMachoSect(ms, "__data");
	msect->addr = va+v;
	msect->size = datsize;
	msect->off = v;

	if(dynptrsize > 0) {
		msect = newMachoSect(ms, "__nl_symbol_ptr");
		msect->addr = va+v+datsize;
		msect->size = dynptrsize;
		msect->align = 2;
		msect->flag = 6;	/* section with nonlazy symbol pointers */
		/*
		 * The reserved1 field is supposed to be the index of
		 * the first entry in the list of symbol table indexes
		 * in isymtab for the symbols we need.  We only use
		 * pointers, so we need the entire list, so the index
		 * here should be 0, which luckily is what the Mach-O
		 * writing code emits by default for this not really reserved field.
		msect->reserved1 = 0; - first indirect symbol table entry we need
		 */
	}

	msect = newMachoSect(ms, "__bss");
	msect->addr = va+v+datsize+dynptrsize;
	msect->size = bsssize;
	msect->flag = 1;	/* flag - zero fill */

	switch(thechar) {
	default:
		diag("unknown macho architecture");
		errorexit();
	case '6':
		ml = newMachoLoad(5, 42+2);	/* unix thread */
		ml->data[0] = 4;	/* thread type */
		ml->data[1] = 42;	/* word count */
		ml->data[2+32] = entryvalue();	/* start pc */
		ml->data[2+32+1] = entryvalue()>>32;
		break;
	case '8':
		ml = newMachoLoad(5, 16+2);	/* unix thread */
		ml->data[0] = 1;	/* thread type */
		ml->data[1] = 16;	/* word count */
		ml->data[2+10] = entryvalue();	/* start pc */
		break;
	}

	if(!debug['d']) {
		int nsym;

		nsym = dynptrsize/ptrsize;

		ms = newMachoSeg("__LINKEDIT", 0);
		ms->vaddr = va+v+rnd(datsize+dynptrsize+bsssize, INITRND);
		ms->vsize = nlinkdata+nstrtab;
		ms->fileoffset = linkoff;
		ms->filesize = nlinkdata+nstrtab;
		ms->prot1 = 7;
		ms->prot2 = 3;

		ml = newMachoLoad(2, 4);	/* LC_SYMTAB */
		ml->data[0] = linkoff;	/* symoff */
		ml->data[1] = nsym;	/* nsyms */
		ml->data[2] = linkoff + nlinkdata;	/* stroff */
		ml->data[3] = nstrtab;	/* strsize */

		ml = newMachoLoad(11, 18);	/* LC_DYSYMTAB */
		ml->data[0] = 0;	/* ilocalsym */
		ml->data[1] = 0;	/* nlocalsym */
		ml->data[2] = 0;	/* iextdefsym */
		ml->data[3] = nexpsym;	/* nextdefsym */
		ml->data[4] = nexpsym;	/* iundefsym */
		ml->data[5] = nimpsym;	/* nundefsym */
		ml->data[6] = 0;	/* tocoffset */
		ml->data[7] = 0;	/* ntoc */
		ml->data[8] = 0;	/* modtaboff */
		ml->data[9] = 0;	/* nmodtab */
		ml->data[10] = 0;	/* extrefsymoff */
		ml->data[11] = 0;	/* nextrefsyms */
		ml->data[12] = linkoff + nlinkdata - nsym*4;	/* indirectsymoff */
		ml->data[13] = nsym;	/* nindirectsyms */
		ml->data[14] = 0;	/* extreloff */
		ml->data[15] = 0;	/* nextrel */
		ml->data[16] = 0;	/* locreloff */
		ml->data[17] = 0;	/* nlocrel */

		ml = newMachoLoad(14, 6);	/* LC_LOAD_DYLINKER */
		ml->data[0] = 12;	/* offset to string */
		strcpy((char*)&ml->data[1], "/usr/lib/dyld");

		if(ndylib > 0) {	/* add reference to where .so files are installed */
			pkgroot = smprint("%s/pkg/%s_%s", goroot, goos, goarch);
			ml = newMachoLoad(0x80000000 | 0x1c, 1+(strlen(pkgroot)+1+7)/8*2);	/* LC_RPATH */
			ml->data[0] = 12;	/* offset of string from beginning of load */
			strcpy((char*)&ml->data[1], pkgroot);
		}
		for(i=0; i<ndylib; i++) {
			ml = newMachoLoad(12, 4+(strlen(dylib[i])+1+7)/8*2);	/* LC_LOAD_DYLIB */
			ml->data[0] = 24;	/* offset of string from beginning of load */
			ml->data[1] = 0;	/* time stamp */
			ml->data[2] = 0;	/* version */
			ml->data[3] = 0;	/* compatibility version */
			strcpy((char*)&ml->data[4], dylib[i]);
		}
	}

	if(!debug['s']) {
		ms = newMachoSeg("__SYMDAT", 1);
		ms->vaddr = symdatva;
		ms->vsize = 8+symsize+lcsize;
		ms->fileoffset = symo;
		ms->filesize = 8+symsize+lcsize;
		ms->prot1 = 7;
		ms->prot2 = 5;

		md = newMachoDebug();
		md->fileoffset = symo+8;
		md->filesize = symsize;

		md = newMachoDebug();
		md->fileoffset = symo+8+symsize;
		md->filesize = lcsize;
	}

	a = machowrite();
	if(a > MACHORESERVE)
		diag("MACHORESERVE too small: %d > %d", a, MACHORESERVE);
}
