/*
Derived from Plan 9 from User Space's src/libmach/elf.h, elf.c
http://code.swtch.com/plan9port/src/tip/src/libmach/

	Copyright © 2004 Russ Cox.
	Portions Copyright © 2008-2010 Google Inc.
	Portions Copyright © 2010 The Go Authors.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#include	"l.h"
#include	"lib.h"

enum {
	MACHO_FAKE_GOTPCREL = 100,	// from macho.h
	
	N_EXT = 0x01,
	N_TYPE = 0x1e,
	N_STAB = 0xe0,
};

typedef struct MachoObj MachoObj;
typedef struct MachoCmd MachoCmd;
typedef struct MachoSeg MachoSeg;
typedef struct MachoSect MachoSect;
typedef struct MachoRel MachoRel;
typedef struct MachoSymtab MachoSymtab;
typedef struct MachoSym MachoSym;
typedef struct MachoDysymtab MachoDysymtab;

enum
{
	MachoCpuVax = 1,
	MachoCpu68000 = 6,
	MachoCpu386 = 7,
	MachoCpuAmd64 = 0x1000007,
	MachoCpuMips = 8,
	MachoCpu98000 = 10,
	MachoCpuHppa = 11,
	MachoCpuArm = 12,
	MachoCpu88000 = 13,
	MachoCpuSparc = 14,
	MachoCpu860 = 15,
	MachoCpuAlpha = 16,
	MachoCpuPower = 18,

	MachoCmdSegment = 1,
	MachoCmdSymtab = 2,
	MachoCmdSymseg = 3,
	MachoCmdThread = 4,
	MachoCmdDysymtab = 11,
	MachoCmdSegment64 = 25,

	MachoFileObject = 1,
	MachoFileExecutable = 2,
	MachoFileFvmlib = 3,
	MachoFileCore = 4,
	MachoFilePreload = 5,
};

struct MachoSeg
{
	char name[16+1];
	uint64 vmaddr;
	uint64 vmsize;
	uint32 fileoff;
	uint32 filesz;
	uint32 maxprot;
	uint32 initprot;
	uint32 nsect;
	uint32 flags;
	MachoSect *sect;
};

struct MachoSect
{
	char	name[16+1];
	char	segname[16+1];
	uint64 addr;
	uint64 size;
	uint32 off;
	uint32 align;
	uint32 reloff;
	uint32 nreloc;
	uint32 flags;
	uint32 res1;
	uint32 res2;
	LSym *sym;
	
	MachoRel *rel;
};

struct MachoRel
{
	uint32 addr;
	uint32 symnum;
	uint8 pcrel;
	uint8 length;
	uint8 extrn;
	uint8 type;
	uint8 scattered;
	uint32 value;
};

struct MachoSymtab
{
	uint32 symoff;
	uint32 nsym;
	uint32 stroff;
	uint32 strsize;
	
	char *str;
	MachoSym *sym;
};

struct MachoSym
{
	char *name;
	uint8 type;
	uint8 sectnum;
	uint16 desc;
	char kind;
	uint64 value;
	LSym *sym;
};

struct MachoDysymtab
{
	uint32 ilocalsym;
	uint32 nlocalsym;
	uint32 iextdefsym;
	uint32 nextdefsym;
	uint32 iundefsym;
	uint32 nundefsym;
	uint32 tocoff;
	uint32 ntoc;
	uint32 modtaboff;
	uint32 nmodtab;
	uint32 extrefsymoff;
	uint32 nextrefsyms;
	uint32 indirectsymoff;
	uint32 nindirectsyms;
	uint32 extreloff;
	uint32 nextrel;
	uint32 locreloff;
	uint32 nlocrel;
	uint32 *indir;
};

struct MachoCmd
{
	int type;
	uint32 off;
	uint32 size;
	MachoSeg seg;
	MachoSymtab sym;
	MachoDysymtab dsym;
};

struct MachoObj
{
	Biobuf	*f;
	int64	base;	// off in f where Mach-O begins
	int64	len;		// length of Mach-O
	int is64;
	char	*name;

	Endian	*e;
	uint cputype;
	uint subcputype;
	uint32 filetype;
	uint32 flags;
	MachoCmd *cmd;
	uint ncmd;
};

static int
unpackcmd(uchar *p, MachoObj *m, MachoCmd *c, uint type, uint sz)
{
	uint32 (*e4)(uchar*);
	uint64 (*e8)(uchar*);
	MachoSect *s;
	int i;

	e4 = m->e->e32;
	e8 = m->e->e64;

	c->type = type;
	c->size = sz;
	switch(type){
	default:
		return -1;
	case MachoCmdSegment:
		if(sz < 56)
			return -1;
		strecpy(c->seg.name, c->seg.name+sizeof c->seg.name, (char*)p+8);
		c->seg.vmaddr = e4(p+24);
		c->seg.vmsize = e4(p+28);
		c->seg.fileoff = e4(p+32);
		c->seg.filesz = e4(p+36);
		c->seg.maxprot = e4(p+40);
		c->seg.initprot = e4(p+44);
		c->seg.nsect = e4(p+48);
		c->seg.flags = e4(p+52);
		c->seg.sect = mal(c->seg.nsect * sizeof c->seg.sect[0]);
		if(sz < 56+c->seg.nsect*68)
			return -1;
		p += 56;
		for(i=0; i<c->seg.nsect; i++) {
			s = &c->seg.sect[i];
			strecpy(s->name, s->name+sizeof s->name, (char*)p+0);
			strecpy(s->segname, s->segname+sizeof s->segname, (char*)p+16);
			s->addr = e4(p+32);
			s->size = e4(p+36);
			s->off = e4(p+40);
			s->align = e4(p+44);
			s->reloff = e4(p+48);
			s->nreloc = e4(p+52);
			s->flags = e4(p+56);
			s->res1 = e4(p+60);
			s->res2 = e4(p+64);
			p += 68;
		}
		break;
	case MachoCmdSegment64:
		if(sz < 72)
			return -1;
		strecpy(c->seg.name, c->seg.name+sizeof c->seg.name, (char*)p+8);
		c->seg.vmaddr = e8(p+24);
		c->seg.vmsize = e8(p+32);
		c->seg.fileoff = e8(p+40);
		c->seg.filesz = e8(p+48);
		c->seg.maxprot = e4(p+56);
		c->seg.initprot = e4(p+60);
		c->seg.nsect = e4(p+64);
		c->seg.flags = e4(p+68);
		c->seg.sect = mal(c->seg.nsect * sizeof c->seg.sect[0]);
		if(sz < 72+c->seg.nsect*80)
			return -1;
		p += 72;
		for(i=0; i<c->seg.nsect; i++) {
			s = &c->seg.sect[i];
			strecpy(s->name, s->name+sizeof s->name, (char*)p+0);
			strecpy(s->segname, s->segname+sizeof s->segname, (char*)p+16);
			s->addr = e8(p+32);
			s->size = e8(p+40);
			s->off = e4(p+48);
			s->align = e4(p+52);
			s->reloff = e4(p+56);
			s->nreloc = e4(p+60);
			s->flags = e4(p+64);
			s->res1 = e4(p+68);
			s->res2 = e4(p+72);
			// p+76 is reserved
			p += 80;
		}
		break;
	case MachoCmdSymtab:
		if(sz < 24)
			return -1;
		c->sym.symoff = e4(p+8);
		c->sym.nsym = e4(p+12);
		c->sym.stroff = e4(p+16);
		c->sym.strsize = e4(p+20);
		break;
	case MachoCmdDysymtab:
		if(sz < 80)
			return -1;
		c->dsym.ilocalsym = e4(p+8);
		c->dsym.nlocalsym = e4(p+12);
		c->dsym.iextdefsym = e4(p+16);
		c->dsym.nextdefsym = e4(p+20);
		c->dsym.iundefsym = e4(p+24);
		c->dsym.nundefsym = e4(p+28);
		c->dsym.tocoff = e4(p+32);
		c->dsym.ntoc = e4(p+36);
		c->dsym.modtaboff = e4(p+40);
		c->dsym.nmodtab = e4(p+44);
		c->dsym.extrefsymoff = e4(p+48);
		c->dsym.nextrefsyms = e4(p+52);
		c->dsym.indirectsymoff = e4(p+56);
		c->dsym.nindirectsyms = e4(p+60);
		c->dsym.extreloff = e4(p+64);
		c->dsym.nextrel = e4(p+68);
		c->dsym.locreloff = e4(p+72);
		c->dsym.nlocrel = e4(p+76);
		break;
	}
	return 0;
}

static int
macholoadrel(MachoObj *m, MachoSect *sect)
{
	MachoRel *rel, *r;
	uchar *buf, *p;
	int i, n;
	uint32 v;
	
	if(sect->rel != nil || sect->nreloc == 0)
		return 0;
	rel = mal(sect->nreloc * sizeof r[0]);
	n = sect->nreloc * 8;
	buf = mal(n);
	if(Bseek(m->f, m->base + sect->reloff, 0) < 0 || Bread(m->f, buf, n) != n)
		return -1;
	for(i=0; i<sect->nreloc; i++) {
		r = &rel[i];
		p = buf+i*8;
		r->addr = m->e->e32(p);
		
		// TODO(rsc): Wrong interpretation for big-endian bitfields?
		if(r->addr & 0x80000000) {
			// scatterbrained relocation
			r->scattered = 1;
			v = r->addr >> 24;
			r->addr &= 0xFFFFFF;
			r->type = v & 0xF;
			v >>= 4;
			r->length = 1<<(v&3);
			v >>= 2;
			r->pcrel = v & 1;
			r->value = m->e->e32(p+4);
		} else {
			v = m->e->e32(p+4);
			r->symnum = v & 0xFFFFFF;
			v >>= 24;
			r->pcrel = v&1;
			v >>= 1;
			r->length = 1<<(v&3);
			v >>= 2;
			r->extrn = v&1;
			v >>= 1;
			r->type = v;
		}
	}
	sect->rel = rel;
	return 0;
}

static int
macholoaddsym(MachoObj *m, MachoDysymtab *d)
{
	uchar *p;
	int i, n;
	
	n = d->nindirectsyms;
	
	p = mal(n*4);
	if(Bseek(m->f, m->base + d->indirectsymoff, 0) < 0 || Bread(m->f, p, n*4) != n*4)
		return -1;
	
	d->indir = (uint32*)p;
	for(i=0; i<n; i++)
		d->indir[i] = m->e->e32(p+4*i);
	return 0;
}

static int 
macholoadsym(MachoObj *m, MachoSymtab *symtab)
{
	char *strbuf;
	uchar *symbuf, *p;
	int i, n, symsize;
	MachoSym *sym, *s;
	uint32 v;

	if(symtab->sym != nil)
		return 0;

	strbuf = mal(symtab->strsize);
	if(Bseek(m->f, m->base + symtab->stroff, 0) < 0 || Bread(m->f, strbuf, symtab->strsize) != symtab->strsize)
		return -1;
	
	symsize = 12;
	if(m->is64)
		symsize = 16;
	n = symtab->nsym * symsize;
	symbuf = mal(n);
	if(Bseek(m->f, m->base + symtab->symoff, 0) < 0 || Bread(m->f, symbuf, n) != n)
		return -1;
	sym = mal(symtab->nsym * sizeof sym[0]);
	p = symbuf;
	for(i=0; i<symtab->nsym; i++) {
		s = &sym[i];
		v = m->e->e32(p);
		if(v >= symtab->strsize)
			return -1;
		s->name = strbuf + v;
		s->type = p[4];
		s->sectnum = p[5];
		s->desc = m->e->e16(p+6);
		if(m->is64)
			s->value = m->e->e64(p+8);
		else
			s->value = m->e->e32(p+8);
		p += symsize;
	}
	symtab->str = strbuf;
	symtab->sym = sym;
	return 0;
}

void
ldmacho(Biobuf *f, char *pkg, int64 len, char *pn)
{
	int i, j, is64;
	uint64 secaddr;
	uchar hdr[7*4], *cmdp;
	uchar tmp[4];
	uchar *dat;
	ulong ncmd, cmdsz, ty, sz, off;
	MachoObj *m;
	Endian *e;
	int64 base;
	MachoSect *sect;
	MachoRel *rel;
	LSym *s, *s1, *outer;
	MachoCmd *c;
	MachoSymtab *symtab;
	MachoDysymtab *dsymtab;
	MachoSym *sym;
	Reloc *r, *rp;
	char *name;

	ctxt->version++;
	base = Boffset(f);
	if(Bread(f, hdr, sizeof hdr) != sizeof hdr)
		goto bad;

	if((be.e32(hdr)&~1) == 0xFEEDFACE){
		e = &be;
	}else if((le.e32(hdr)&~1) == 0xFEEDFACE){
		e = &le;
	}else{
		werrstr("bad magic - not mach-o file");
		goto bad;
	}

	is64 = e->e32(hdr) == 0xFEEDFACF;
	ncmd = e->e32(hdr+4*4);
	cmdsz = e->e32(hdr+5*4);
	if(ncmd > 0x10000 || cmdsz >= 0x01000000){
		werrstr("implausible mach-o header ncmd=%lud cmdsz=%lud", ncmd, cmdsz);
		goto bad;
	}
	if(is64)
		Bread(f, tmp, 4);	// skip reserved word in header

	m = mal(sizeof(*m)+ncmd*sizeof(MachoCmd)+cmdsz);
	m->f = f;
	m->e = e;
	m->cputype = e->e32(hdr+1*4);
	m->subcputype = e->e32(hdr+2*4);
	m->filetype = e->e32(hdr+3*4);
	m->ncmd = ncmd;
	m->flags = e->e32(hdr+6*4);
	m->is64 = is64;
	m->base = base;
	m->len = len;
	m->name = pn;
	
	switch(thechar) {
	default:
		diag("%s: mach-o %s unimplemented", pn, thestring);
		return;
	case '6':
		if(e != &le || m->cputype != MachoCpuAmd64) {
			diag("%s: mach-o object but not amd64", pn);
			return;
		}
		break;
	case '8':
		if(e != &le || m->cputype != MachoCpu386) {
			diag("%s: mach-o object but not 386", pn);
			return;
		}
		break;
	}

	m->cmd = (MachoCmd*)(m+1);
	off = sizeof hdr;
	cmdp = (uchar*)(m->cmd+ncmd);
	if(Bread(f, cmdp, cmdsz) != cmdsz){
		werrstr("reading cmds: %r");
		goto bad;
	}

	// read and parse load commands
	c = nil;
	symtab = nil;
	dsymtab = nil;
	USED(dsymtab);
	for(i=0; i<ncmd; i++){
		ty = e->e32(cmdp);
		sz = e->e32(cmdp+4);
		m->cmd[i].off = off;
		unpackcmd(cmdp, m, &m->cmd[i], ty, sz);
		cmdp += sz;
		off += sz;
		if(ty == MachoCmdSymtab) {
			if(symtab != nil) {
				werrstr("multiple symbol tables");
				goto bad;
			}
			symtab = &m->cmd[i].sym;
			macholoadsym(m, symtab);
		}
		if(ty == MachoCmdDysymtab) {
			dsymtab = &m->cmd[i].dsym;
			macholoaddsym(m, dsymtab);
		}
		if((is64 && ty == MachoCmdSegment64) || (!is64 && ty == MachoCmdSegment)) {
			if(c != nil) {
				werrstr("multiple load commands");
				goto bad;
			}
			c = &m->cmd[i];
		}
	}

	// load text and data segments into memory.
	// they are not as small as the load commands, but we'll need
	// the memory anyway for the symbol images, so we might
	// as well use one large chunk.
	if(c == nil) {
		werrstr("no load command");
		goto bad;
	}
	if(symtab == nil) {
		// our work is done here - no symbols means nothing can refer to this file
		return;
	}

	if(c->seg.fileoff+c->seg.filesz >= len) {
		werrstr("load segment out of range");
		goto bad;
	}

	dat = mal(c->seg.filesz);
	if(Bseek(f, m->base + c->seg.fileoff, 0) < 0 || Bread(f, dat, c->seg.filesz) != c->seg.filesz) {
		werrstr("cannot load object data: %r");
		goto bad;
	}
	
	for(i=0; i<c->seg.nsect; i++) {
		sect = &c->seg.sect[i];
		if(strcmp(sect->segname, "__TEXT") != 0 && strcmp(sect->segname, "__DATA") != 0)
			continue;
		if(strcmp(sect->name, "__eh_frame") == 0)
			continue;
		name = smprint("%s(%s/%s)", pkg, sect->segname, sect->name);
		s = linklookup(ctxt, name, ctxt->version);
		if(s->type != 0) {
			werrstr("duplicate %s/%s", sect->segname, sect->name);
			goto bad;
		}
		free(name);

		s->np = sect->size;
		s->size = s->np;
		if((sect->flags & 0xff) == 1) // S_ZEROFILL
			s->p = mal(s->size);
		else {
			s->p = dat + sect->addr - c->seg.vmaddr;
		}
		
		if(strcmp(sect->segname, "__TEXT") == 0) {
			if(strcmp(sect->name, "__text") == 0)
				s->type = STEXT;
			else
				s->type = SRODATA;
		} else {
			if (strcmp(sect->name, "__bss") == 0) {
				s->type = SNOPTRBSS;
				s->np = 0;
			} else
				s->type = SNOPTRDATA;
		}
		sect->sym = s;
	}
	
	// enter sub-symbols into symbol table.
	// have to guess sizes from next symbol.
	for(i=0; i<symtab->nsym; i++) {
		int v;
		sym = &symtab->sym[i];
		if(sym->type&N_STAB)
			continue;
		// TODO: check sym->type against outer->type.
		name = sym->name;
		if(name[0] == '_' && name[1] != '\0')
			name++;
		v = 0;
		if(!(sym->type&N_EXT))
			v = ctxt->version;
		s = linklookup(ctxt, name, v);
		if(!(sym->type&N_EXT))
			s->dupok = 1;
		sym->sym = s;
		if(sym->sectnum == 0)	// undefined
			continue;
		if(sym->sectnum > c->seg.nsect) {
			werrstr("reference to invalid section %d", sym->sectnum);
			goto bad;
		}
		sect = &c->seg.sect[sym->sectnum-1];
		outer = sect->sym;
		if(outer == nil) {
			werrstr("reference to invalid section %s/%s", sect->segname, sect->name);
			continue;
		}
		if(s->outer != S) {
			if(s->dupok)
				continue;
			diag("%s: duplicate symbol reference: %s in both %s and %s", pn, s->name, s->outer->name, sect->sym->name);
			errorexit();
		}
		s->type = outer->type | SSUB;
		s->sub = outer->sub;
		outer->sub = s;
		s->outer = outer;
		s->value = sym->value - sect->addr;
		if(!(s->cgoexport & CgoExportDynamic))
			s->dynimplib = nil;	// satisfy dynimport
		if(outer->type == STEXT) {
			if(s->external && !s->dupok)
				diag("%s: duplicate definition of %s", pn, s->name);
			s->external = 1;
		}
		sym->sym = s;
	}

	// Sort outer lists by address, adding to textp.
	// This keeps textp in increasing address order.
	for(i=0; i<c->seg.nsect; i++) {
		sect = &c->seg.sect[i];
		if((s = sect->sym) == S)
			continue;
		if(s->sub) {
			s->sub = listsort(s->sub, valuecmp, offsetof(LSym, sub));
			
			// assign sizes, now that we know symbols in sorted order.
			for(s1 = s->sub; s1 != S; s1 = s1->sub) {
				if(s1->sub)
					s1->size = s1->sub->value - s1->value;
				else
					s1->size = s->value + s->size - s1->value;
			}
		}
		if(s->type == STEXT) {
			if(s->onlist)
				sysfatal("symbol %s listed multiple times", s->name);
			s->onlist = 1;
			if(ctxt->etextp)
				ctxt->etextp->next = s;
			else
				ctxt->textp = s;
			ctxt->etextp = s;
			for(s1 = s->sub; s1 != S; s1 = s1->sub) {
				if(s1->onlist)
					sysfatal("symbol %s listed multiple times", s1->name);
				s1->onlist = 1;
				ctxt->etextp->next = s1;
				ctxt->etextp = s1;
			}
		}
	}

	// load relocations
	for(i=0; i<c->seg.nsect; i++) {
		sect = &c->seg.sect[i];
		if((s = sect->sym) == S)
			continue;
		macholoadrel(m, sect);
		if(sect->rel == nil)
			continue;
		r = mal(sect->nreloc*sizeof r[0]);
		rp = r;
		rel = sect->rel;
		for(j=0; j<sect->nreloc; j++, rel++) {
			if(rel->scattered) {
				int k;
				MachoSect *ks;

				if(thechar != '8') {
					// mach-o only uses scattered relocation on 32-bit platforms
					diag("unexpected scattered relocation");
					continue;
				}

				// on 386, rewrite scattered 4/1 relocation and some
				// scattered 2/1 relocation into the pseudo-pc-relative
				// reference that it is.
				// assume that the second in the pair is in this section
				// and use that as the pc-relative base.
				if(j+1 >= sect->nreloc) {
					werrstr("unsupported scattered relocation %d", (int)rel->type);
					goto bad;
				}
				if(!(rel+1)->scattered || (rel+1)->type != 1 ||
				   (rel->type != 4 && rel->type != 2) ||
				   (rel+1)->value < sect->addr || (rel+1)->value >= sect->addr+sect->size) {
					werrstr("unsupported scattered relocation %d/%d", (int)rel->type, (int)(rel+1)->type);
					goto bad;
				}

				rp->siz = rel->length;
				rp->off = rel->addr;
				
				// NOTE(rsc): I haven't worked out why (really when)
				// we should ignore the addend on a
				// scattered relocation, but it seems that the
				// common case is we ignore it.
				// It's likely that this is not strictly correct
				// and that the math should look something
				// like the non-scattered case below.
				rp->add = 0;
				
				// want to make it pc-relative aka relative to rp->off+4
				// but the scatter asks for relative to off = (rel+1)->value - sect->addr.
				// adjust rp->add accordingly.
				rp->type = R_PCREL;
				rp->add += (rp->off+4) - ((rel+1)->value - sect->addr);
				
				// now consider the desired symbol.
				// find the section where it lives.
				for(k=0; k<c->seg.nsect; k++) {
					ks = &c->seg.sect[k];
					if(ks->addr <= rel->value && rel->value < ks->addr+ks->size)
						goto foundk;
				}
				werrstr("unsupported scattered relocation: invalid address %#ux", rel->addr);
				goto bad;
			foundk:
				if(ks->sym != S) {
					rp->sym = ks->sym;
					rp->add += rel->value - ks->addr;
				} else if(strcmp(ks->segname, "__IMPORT") == 0 && strcmp(ks->name, "__pointers") == 0) {
					// handle reference to __IMPORT/__pointers.
					// how much worse can this get?
					// why are we supporting 386 on the mac anyway?
					rp->type = 512 + MACHO_FAKE_GOTPCREL;
					// figure out which pointer this is a reference to.
					k = ks->res1 + (rel->value - ks->addr) / 4;
					// load indirect table for __pointers
					// fetch symbol number
					if(dsymtab == nil || k < 0 || k >= dsymtab->nindirectsyms || dsymtab->indir == nil) {
						werrstr("invalid scattered relocation: indirect symbol reference out of range");
						goto bad;
					}
					k = dsymtab->indir[k];
					if(k < 0 || k >= symtab->nsym) {
						werrstr("invalid scattered relocation: symbol reference out of range");
						goto bad;
					}
					rp->sym = symtab->sym[k].sym;
				} else {
					werrstr("unsupported scattered relocation: reference to %s/%s", ks->segname, ks->name);
					goto bad;
				}
				rp++;
				// skip #1 of 2 rel; continue skips #2 of 2.
				rel++;
				j++;
				continue;
			}

			rp->siz = rel->length;
			rp->type = 512 + (rel->type<<1) + rel->pcrel;
			rp->off = rel->addr;

			// Handle X86_64_RELOC_SIGNED referencing a section (rel->extrn == 0).
			if (thechar == '6' && rel->extrn == 0 && rel->type == 1) {
				// Calculate the addend as the offset into the section.
				//
				// The rip-relative offset stored in the object file is encoded
				// as follows:
				//    
				//    movsd	0x00000360(%rip),%xmm0
				//
				// To get the absolute address of the value this rip-relative address is pointing
				// to, we must add the address of the next instruction to it. This is done by
				// taking the address of the relocation and adding 4 to it (since the rip-relative
				// offset can at most be 32 bits long).  To calculate the offset into the section the
				// relocation is referencing, we subtract the vaddr of the start of the referenced
				// section found in the original object file.
				//
				// [For future reference, see Darwin's /usr/include/mach-o/x86_64/reloc.h]
				secaddr = c->seg.sect[rel->symnum-1].addr;
				rp->add = (int32)e->e32(s->p+rp->off) + rp->off + 4 - secaddr;
			} else
				rp->add = (int32)e->e32(s->p+rp->off);

			// For i386 Mach-O PC-relative, the addend is written such that
			// it *is* the PC being subtracted.  Use that to make
			// it match our version of PC-relative.
			if(rel->pcrel && thechar == '8')
				rp->add += rp->off+rp->siz;
			if(!rel->extrn) {
				if(rel->symnum < 1 || rel->symnum > c->seg.nsect) {
					werrstr("invalid relocation: section reference out of range %d vs %d", rel->symnum, c->seg.nsect);
					goto bad;
				}
				rp->sym = c->seg.sect[rel->symnum-1].sym;
				if(rp->sym == nil) {
					werrstr("invalid relocation: %s", c->seg.sect[rel->symnum-1].name);
					goto bad;
				}
				// References to symbols in other sections
				// include that information in the addend.
				// We only care about the delta from the 
				// section base.
				if(thechar == '8')
					rp->add -= c->seg.sect[rel->symnum-1].addr;
			} else {
				if(rel->symnum >= symtab->nsym) {
					werrstr("invalid relocation: symbol reference out of range");
					goto bad;
				}
				rp->sym = symtab->sym[rel->symnum].sym;
			}
			rp++;
		}			
		qsort(r, rp - r, sizeof r[0], rbyoff);
		s->r = r;
		s->nr = rp - r;
	}
	return;

bad:
	diag("%s: malformed mach-o file: %r", pn);
}
