예제 #1
0
파일: asm.c 프로젝트: zhuowei/go-1-2-haiku
void
elfsetupplt(void)
{
	Sym *plt, *got;
	
	plt = lookup(".plt", 0);
	got = lookup(".got.plt", 0);
	if(plt->size == 0) {
		// pushl got+4
		adduint8(plt, 0xff);
		adduint8(plt, 0x35);
		addaddrplus(plt, got, 4);
		
		// jmp *got+8
		adduint8(plt, 0xff);
		adduint8(plt, 0x25);
		addaddrplus(plt, got, 8);

		// zero pad
		adduint32(plt, 0);
		
		// assume got->size == 0 too
		addaddrplus(got, lookup(".dynamic", 0), 0);
		adduint32(got, 0);
		adduint32(got, 0);
	}
}
예제 #2
0
파일: asm.c 프로젝트: serge-hulne/golang
void
elfsetupplt(void)
{
	Sym *plt, *got;

	plt = lookup(".plt", 0);
	got = lookup(".got.plt", 0);
	if(plt->size == 0) {
		// pushq got+8(IP)
		adduint8(plt, 0xff);
		adduint8(plt, 0x35);
		addpcrelplus(plt, got, 8);
		
		// jmpq got+16(IP)
		adduint8(plt, 0xff);
		adduint8(plt, 0x25);
		addpcrelplus(plt, got, 16);
		
		// nopl 0(AX)
		adduint32(plt, 0x00401f0f);
		
		// assume got->size == 0 too
		addaddrplus(got, lookup(".dynamic", 0), 0);
		adduint64(got, 0);
		adduint64(got, 0);
	}
}
예제 #3
0
파일: asm.c 프로젝트: 8l/go
void
adddynsym(Link *ctxt, LSym *s)
{
	LSym *d;
	int t;
	char *name;

	if(s->dynid >= 0)
		return;

	if(iself) {
		s->dynid = nelfsym++;

		d = linklookup(ctxt, ".dynsym", 0);

		name = s->extname;
		adduint32(ctxt, d, addstring(linklookup(ctxt, ".dynstr", 0), name));
		/* type */
		t = STB_GLOBAL << 4;
		if(s->cgoexport && (s->type&SMASK) == STEXT)
			t |= STT_FUNC;
		else
			t |= STT_OBJECT;
		adduint8(ctxt, d, t);
	
		/* reserved */
		adduint8(ctxt, d, 0);
	
		/* section where symbol is defined */
		if(s->type == SDYNIMPORT)
			adduint16(ctxt, d, SHN_UNDEF);
		else
			adduint16(ctxt, d, 1);
	
		/* value */
		if(s->type == SDYNIMPORT)
			adduint64(ctxt, d, 0);
		else
			addaddr(ctxt, d, s);
	
		/* size of object */
		adduint64(ctxt, d, s->size);
	
		if(!(s->cgoexport & CgoExportDynamic) && s->dynimplib && needlib(s->dynimplib)) {
			elfwritedynent(linklookup(ctxt, ".dynamic", 0), DT_NEEDED,
				addstring(linklookup(ctxt, ".dynstr", 0), s->dynimplib));
		}
	} else if(HEADTYPE == Hdarwin) {
		diag("adddynsym: missed symbol %s (%s)", s->name, s->extname);
	} else if(HEADTYPE == Hwindows) {
		// already taken care of
	} else {
		diag("adddynsym: unsupported binary format");
	}
}
예제 #4
0
파일: data.c 프로젝트: hfeeki/golang
void
dynrelocsym(Sym *s)
{
	Reloc *r;
	Sym *rel;
	Sym *got;
	
	if(HEADTYPE == Hwindows) {
		Sym *rel, *targ;

		rel = lookup(".rel", 0);
		if(s == rel)
			return;
		for(r=s->r; r<s->r+s->nr; r++) {
			targ = r->sym;
			if(r->sym->plt == -2 && r->sym->got != -2) { // make dynimport JMP table for PE object files.
				targ->plt = rel->size;
				r->sym = rel;
				r->add = targ->plt;

				// jmp *addr
				if(thechar == '8') {
					adduint8(rel, 0xff);
					adduint8(rel, 0x25);
					addaddr(rel, targ);
					adduint8(rel, 0x90);
					adduint8(rel, 0x90);
				} else {
					adduint8(rel, 0xff);
					adduint8(rel, 0x24);
					adduint8(rel, 0x25);
					addaddrplus4(rel, targ, 0);
					adduint8(rel, 0x90);
				}
			} else if(r->sym->plt >= 0) {
				r->sym = rel;
				r->add = targ->plt;
			}
		}
		return;
	}

	got = rel = nil;
	if(flag_shared) {
		rel = lookuprel();
		got = lookup(".got", 0);
	}
	s->rel_ro = 0;
	for(r=s->r; r<s->r+s->nr; r++) {
		if(r->sym != S && r->sym->type == SDYNIMPORT || r->type >= 256)
			adddynrel(s, r);
		if(flag_shared && r->sym != S && s->type != SDYNIMPORT && r->type == D_ADDR
				&& (s == got || s->type == SDATA || s->type == SGOSTRING || s->type == STYPE || s->type == SRODATA)) {
			// Create address based RELATIVE relocation
			adddynrela(rel, s, r);
			if(s->type < SNOPTRDATA)
				s->rel_ro = 1;
		}
	}
}
예제 #5
0
파일: data.c 프로젝트: LEEWEN-DALIAN/golang
void
dynrelocsym(LSym *s)
{
	Reloc *r;

	if(HEADTYPE == Hwindows) {
		LSym *rel, *targ;

		rel = linklookup(ctxt, ".rel", 0);
		if(s == rel)
			return;
		for(r=s->r; r<s->r+s->nr; r++) {
			targ = r->sym;
			if(targ == nil)
				continue;
			if(!targ->reachable)
				diag("internal inconsistency: dynamic symbol %s is not reachable.", targ->name);
			if(r->sym->plt == -2 && r->sym->got != -2) { // make dynimport JMP table for PE object files.
				targ->plt = rel->size;
				r->sym = rel;
				r->add = targ->plt;

				// jmp *addr
				if(thechar == '8') {
					adduint8(ctxt, rel, 0xff);
					adduint8(ctxt, rel, 0x25);
					addaddr(ctxt, rel, targ);
					adduint8(ctxt, rel, 0x90);
					adduint8(ctxt, rel, 0x90);
				} else {
					adduint8(ctxt, rel, 0xff);
					adduint8(ctxt, rel, 0x24);
					adduint8(ctxt, rel, 0x25);
					addaddrplus4(ctxt, rel, targ, 0);
					adduint8(ctxt, rel, 0x90);
				}
			} else if(r->sym->plt >= 0) {
				r->sym = rel;
				r->add = targ->plt;
			}
		}
		return;
	}

	for(r=s->r; r<s->r+s->nr; r++) {
		if(r->sym != S && r->sym->type == SDYNIMPORT || r->type >= 256) {
			if(r->sym != S && !r->sym->reachable)
				diag("internal inconsistency: dynamic symbol %s is not reachable.", r->sym->name);
			adddynrel(s, r);
		}
	}
}
예제 #6
0
파일: asm.c 프로젝트: zhuowei/go-1-2-haiku
static void
addpltsym(Sym *s)
{
	Sym *plt, *got, *rel;
	
	if(s->plt >= 0)
		return;

	adddynsym(s);
	
	if(iself) {
		plt = lookup(".plt", 0);
		got = lookup(".got.plt", 0);
		rel = lookup(".rel.plt", 0);
		if(plt->size == 0)
			elfsetupplt();
		
		// jmpq *got+size
		adduint8(plt, 0xff);
		adduint8(plt, 0x25);
		addaddrplus(plt, got, got->size);
		
		// add to got: pointer to current pos in plt
		addaddrplus(got, plt, plt->size);
		
		// pushl $x
		adduint8(plt, 0x68);
		adduint32(plt, rel->size);
		
		// jmp .plt
		adduint8(plt, 0xe9);
		adduint32(plt, -(plt->size+4));
		
		// rel
		addaddrplus(rel, got, got->size-4);
		adduint32(rel, ELF32_R_INFO(s->dynid, R_386_JMP_SLOT));
		
		s->plt = plt->size - 16;
	} else if(HEADTYPE == Hdarwin) {
		// Same laziness as in 6l.
		
		Sym *plt;

		plt = lookup(".plt", 0);

		addgotsym(s);

		adduint32(lookup(".linkedit.plt", 0), s->dynid);

		// jmpq *got+size(IP)
		s->plt = plt->size;

		adduint8(plt, 0xff);
		adduint8(plt, 0x25);
		addaddrplus(plt, lookup(".got", 0), s->got);
	} else {
		diag("addpltsym: unsupported binary format");
	}
}
예제 #7
0
파일: data.c 프로젝트: pipul/lab
void
dynrelocsym(Sym *s)
{
	Reloc *r;
	
	if(HEADTYPE == Hwindows) {
		Sym *rel, *targ;
		
		rel = lookup(".rel", 0);
		if(s == rel)
			return;
		for(r=s->r; r<s->r+s->nr; r++) {
			targ = r->sym;
			if(r->sym->plt == -2 && r->sym->got != -2) { // make dynimport JMP table for PE object files.
				targ->plt = rel->size;
				r->sym = rel;
				r->add = targ->plt;
				
				// jmp *addr
				if(thechar == '8') {
					adduint8(rel, 0xff);
					adduint8(rel, 0x25);
					addaddr(rel, targ);
					adduint8(rel, 0x90);
					adduint8(rel, 0x90);
				} else {
					adduint8(rel, 0xff);
					adduint8(rel, 0x24);
					adduint8(rel, 0x25);
					addaddrplus4(rel, targ, 0);
					adduint8(rel, 0x90);
				}
			} else if(r->sym->plt >= 0) {
				r->sym = rel;
				r->add = targ->plt;
			}
		}
		return;
	}

	for(r=s->r; r<s->r+s->nr; r++)
		if(r->sym->type == SDYNIMPORT || r->type >= 256)
			adddynrel(s, r);
}
예제 #8
0
파일: asm.c 프로젝트: zhuowei/go-1-2-haiku
void
adddynsym(Sym *s)
{
	Sym *d;
	int t;
	char *name;
	
	if(s->dynid >= 0)
		return;
	
	if(iself) {
		s->dynid = nelfsym++;
		
		d = lookup(".dynsym", 0);

		/* name */
		name = s->extname;
		adduint32(d, addstring(lookup(".dynstr", 0), name));
		
		/* value */
		if(s->type == SDYNIMPORT)
			adduint32(d, 0);
		else
			addaddr(d, s);
		
		/* size */
		adduint32(d, 0);
	
		/* type */
		t = STB_GLOBAL << 4;
		if(s->cgoexport && (s->type&SMASK) == STEXT)
			t |= STT_FUNC;
		else
			t |= STT_OBJECT;
		adduint8(d, t);
		adduint8(d, 0);
	
		/* shndx */
		if(s->type == SDYNIMPORT)
			adduint16(d, SHN_UNDEF);
		else {
			switch(s->type) {
			default:
			case STEXT:
				t = 11;
				break;
			case SRODATA:
				t = 12;
				break;
			case SDATA:
				t = 13;
				break;
			case SBSS:
				t = 14;
				break;
			}
			adduint16(d, t);
		}
	} else if(HEADTYPE == Hdarwin) {
		diag("adddynsym: missed symbol %s (%s)", s->name, s->extname);
	} else if(HEADTYPE == Hwindows) {
		// already taken care of
	} else {
		diag("adddynsym: unsupported binary format");
	}
}
예제 #9
0
void
loadlib(void)
{
	int i, w, x;
	LSym *s, *gmsym;
	char* cgostrsym;

	if(flag_shared) {
		s = linklookup(ctxt, "runtime.islibrary", 0);
		s->dupok = 1;
		adduint8(ctxt, s, 1);
	}

	loadinternal("runtime");
	if(thechar == '5')
		loadinternal("math");
	if(flag_race)
		loadinternal("runtime/race");

	for(i=0; i<ctxt->libraryp; i++) {
		if(debug['v'] > 1)
			Bprint(&bso, "%5.2f autolib: %s (from %s)\n", cputime(), ctxt->library[i].file, ctxt->library[i].objref);
		iscgo |= strcmp(ctxt->library[i].pkg, "runtime/cgo") == 0;
		objfile(ctxt->library[i].file, ctxt->library[i].pkg);
	}
	
	if(linkmode == LinkExternal && !iscgo) {
		// This indicates a user requested -linkmode=external.
		// The startup code uses an import of runtime/cgo to decide
		// whether to initialize the TLS.  So give it one.  This could
		// be handled differently but it's an unusual case.
		loadinternal("runtime/cgo");

		// Pretend that we really imported the package.
		s = linklookup(ctxt, "go.importpath.runtime/cgo.", 0);
		s->type = SDATA;
		s->dupok = 1;
		s->reachable = 1;

		// Provided by the code that imports the package.
		// Since we are simulating the import, we have to provide this string.
		cgostrsym = "go.string.\"runtime/cgo\"";
		if(linkrlookup(ctxt, cgostrsym, 0) == nil)
			addstrdata(cgostrsym, "runtime/cgo");
	}

	if(linkmode == LinkAuto) {
		if(iscgo && externalobj)
			linkmode = LinkExternal;
		else
			linkmode = LinkInternal;
	}

	if(linkmode == LinkInternal) {
		// Drop all the cgo_import_static declarations.
		// Turns out we won't be needing them.
		for(s = ctxt->allsym; s != S; s = s->allsym)
			if(s->type == SHOSTOBJ) {
				// If a symbol was marked both
				// cgo_import_static and cgo_import_dynamic,
				// then we want to make it cgo_import_dynamic
				// now.
				if(s->extname != nil && s->dynimplib != nil && s->cgoexport == 0) {
					s->type = SDYNIMPORT;
				} else
					s->type = 0;
			}
	}
	
	gmsym = linklookup(ctxt, "runtime.tlsgm", 0);
	gmsym->type = STLSBSS;
	gmsym->size = 2*PtrSize;
	gmsym->hide = 1;
	gmsym->reachable = 1;

	// Now that we know the link mode, trim the dynexp list.
	x = CgoExportDynamic;
	if(linkmode == LinkExternal)
		x = CgoExportStatic;
	w = 0;
	for(i=0; i<ndynexp; i++)
		if(dynexp[i]->cgoexport & x)
			dynexp[w++] = dynexp[i];
	ndynexp = w;
	
	// In internal link mode, read the host object files.
	if(linkmode == LinkInternal)
		hostobjs();
	else
		hostlinksetup();

	// We've loaded all the code now.
	// If there are no dynamic libraries needed, gcc disables dynamic linking.
	// Because of this, glibc's dynamic ELF loader occasionally (like in version 2.13)
	// assumes that a dynamic binary always refers to at least one dynamic library.
	// Rather than be a source of test cases for glibc, disable dynamic linking
	// the same way that gcc would.
	//
	// Exception: on OS X, programs such as Shark only work with dynamic
	// binaries, so leave it enabled on OS X (Mach-O) binaries.
	// Also leave it enabled on Solaris which doesn't support
	// statically linked binaries.
	if(!flag_shared && !havedynamic && HEADTYPE != Hdarwin && HEADTYPE != Hsolaris)
		debug['d'] = 1;
	
	importcycles();
}
예제 #10
0
파일: asm.c 프로젝트: timnau/golang
void
adddynsym(Sym *s)
{
    Sym *d, *str;
    int t;
    char *name;
    vlong off;

    if(s->dynid >= 0)
        return;

    if(s->dynimpname == nil)
        diag("adddynsym: no dynamic name for %s", s->name);

    if(iself) {
        s->dynid = nelfsym++;

        d = lookup(".dynsym", 0);

        /* name */
        name = s->dynimpname;
        if(name == nil)
            name = s->name;
        adduint32(d, addstring(lookup(".dynstr", 0), name));

        /* value */
        if(s->type == SDYNIMPORT)
            adduint32(d, 0);
        else
            addaddr(d, s);

        /* size */
        adduint32(d, 0);

        /* type */
        t = STB_GLOBAL << 4;
        if(s->dynexport && (s->type&SMASK) == STEXT)
            t |= STT_FUNC;
        else
            t |= STT_OBJECT;
        adduint8(d, t);
        adduint8(d, 0);

        /* shndx */
        if(!s->dynexport && s->dynimpname != nil)
            adduint16(d, SHN_UNDEF);
        else {
            switch(s->type) {
            default:
            case STEXT:
                t = 11;
                break;
            case SRODATA:
                t = 12;
                break;
            case SDATA:
                t = 13;
                break;
            case SBSS:
                t = 14;
                break;
            }
            adduint16(d, t);
        }
    } else if(HEADTYPE == Hdarwin) {
        // Mach-O symbol nlist32
        d = lookup(".dynsym", 0);
        name = s->dynimpname;
        if(name == nil)
            name = s->name;
        if(d->size == 0 && ndynexp > 0) { // pre-allocate for dynexps
            symgrow(d, ndynexp*12);
        }
        if(s->dynid <= -100) { // pre-allocated, see cmd/ld/go.c:^sortdynexp()
            s->dynid = -s->dynid-100;
            off = s->dynid*12;
        } else {
            off = d->size;
            s->dynid = off/12;
        }
        // darwin still puts _ prefixes on all C symbols
        str = lookup(".dynstr", 0);
        setuint32(d, off, str->size);
        off += 4;
        adduint8(str, '_');
        addstring(str, name);
        if(s->type == SDYNIMPORT) {
            setuint8(d, off, 0x01); // type - N_EXT - external symbol
            off++;
            setuint8(d, off, 0); // section
            off++;
        } else {
            setuint8(d, off, 0x0f);
            off++;
            switch(s->type) {
            default:
            case STEXT:
                setuint8(d, off, 1);
                break;
            case SDATA:
                setuint8(d, off, 2);
                break;
            case SBSS:
                setuint8(d, off, 4);
                break;
            }
            off++;
        }
        setuint16(d, off, 0); // desc
        off += 2;
        if(s->type == SDYNIMPORT)
            setuint32(d, off, 0); // value
        else
            setaddr(d, off, s);
        off += 4;
    } else if(HEADTYPE != Hwindows) {
        diag("adddynsym: unsupported binary format");
    }
}
예제 #11
0
파일: asm.c 프로젝트: serge-hulne/golang
static void
addpltsym(Sym *s)
{
	if(s->plt >= 0)
		return;
	
	adddynsym(s);
	
	if(iself) {
		Sym *plt, *got, *rela;

		plt = lookup(".plt", 0);
		got = lookup(".got.plt", 0);
		rela = lookup(".rela.plt", 0);
		if(plt->size == 0)
			elfsetupplt();
		
		// jmpq *got+size(IP)
		adduint8(plt, 0xff);
		adduint8(plt, 0x25);
		addpcrelplus(plt, got, got->size);
	
		// add to got: pointer to current pos in plt
		addaddrplus(got, plt, plt->size);
		
		// pushq $x
		adduint8(plt, 0x68);
		adduint32(plt, (got->size-24-8)/8);
		
		// jmpq .plt
		adduint8(plt, 0xe9);
		adduint32(plt, -(plt->size+4));
		
		// rela
		addaddrplus(rela, got, got->size-8);
		adduint64(rela, ELF64_R_INFO(s->dynid, R_X86_64_JMP_SLOT));
		adduint64(rela, 0);
		
		s->plt = plt->size - 16;
	} else if(HEADTYPE == Hdarwin) {
		// To do lazy symbol lookup right, we're supposed
		// to tell the dynamic loader which library each 
		// symbol comes from and format the link info
		// section just so.  I'm too lazy (ha!) to do that
		// so for now we'll just use non-lazy pointers,
		// which don't need to be told which library to use.
		//
		// http://networkpx.blogspot.com/2009/09/about-lcdyldinfoonly-command.html
		// has details about what we're avoiding.

		Sym *plt;
		
		addgotsym(s);
		plt = lookup(".plt", 0);

		adduint32(lookup(".linkedit.plt", 0), s->dynid);

		// jmpq *got+size(IP)
		s->plt = plt->size;

		adduint8(plt, 0xff);
		adduint8(plt, 0x25);
		addpcrelplus(plt, lookup(".got", 0), s->got);
	} else {
		diag("addpltsym: unsupported binary format");
	}
}
예제 #12
0
파일: asm.c 프로젝트: machinaut/go
void
adddynsym(Sym *s)
{
	Sym *d, *str;
	int t;
	char *name;
	
	if(s->dynid >= 0)
		return;
	
	if(s->dynimpname == nil)
		diag("adddynsym: no dynamic name for %s", s->name, *(int32*)0);

	if(iself) {
		s->dynid = nelfsym++;
		
		d = lookup(".dynsym", 0);

		/* name */
		name = s->dynimpname;
		if(name == nil)
			name = s->name;
		adduint32(d, addstring(lookup(".dynstr", 0), name));
		
		/* value */
		if(s->type == SDYNIMPORT)
			adduint32(d, 0);
		else
			addaddr(d, s);
		
		/* size */
		adduint32(d, 0);
	
		/* type */
		t = STB_GLOBAL << 4;
		if(s->dynexport && s->type == STEXT)
			t |= STT_FUNC;
		else
			t |= STT_OBJECT;
		adduint8(d, t);
		adduint8(d, 0);
	
		/* shndx */
		if(!s->dynexport && s->dynimpname != nil)
			adduint16(d, SHN_UNDEF);
		else {
			switch(s->type) {
			default:
			case STEXT:
				t = 11;
				break;
			case SRODATA:
				t = 12;
				break;
			case SDATA:
				t = 13;
				break;
			case SBSS:
				t = 14;
				break;
			}
			adduint16(d, t);
		}
	} else if(HEADTYPE == Hdarwin) {
		// Mach-O symbol nlist32
		d = lookup(".dynsym", 0);
		name = s->dynimpname;
		if(name == nil)
			name = s->name;
		s->dynid = d->size/12;
		// darwin still puts _ prefixes on all C symbols
		str = lookup(".dynstr", 0);
		adduint32(d, str->size);
		adduint8(str, '_');
		addstring(str, name);
		adduint8(d, 0x01);	// type - N_EXT - external symbol
		adduint8(d, 0);	// section
		adduint16(d, 0);	// desc
		adduint32(d, 0);	// value
	} else if(HEADTYPE != Hwindows) {
		diag("adddynsym: unsupported binary format");
	}
}
예제 #13
0
파일: asm.c 프로젝트: qmwd2006/go-sctp
void
adddynsym(Sym *s)
{
	Sym *d, *str;
	int t;
	char *name;

	if(s->dynid >= 0)
		return;

	if(s->dynimpname == nil)
		diag("adddynsym: no dynamic name for %s", s->name);

	if(iself) {
		s->dynid = nelfsym++;

		d = lookup(".dynsym", 0);

		name = s->dynimpname;
		if(name == nil)
			name = s->name;
		adduint32(d, addstring(lookup(".dynstr", 0), name));
		/* type */
		t = STB_GLOBAL << 4;
		if(s->dynexport && s->type == STEXT)
			t |= STT_FUNC;
		else
			t |= STT_OBJECT;
		adduint8(d, t);
	
		/* reserved */
		adduint8(d, 0);
	
		/* section where symbol is defined */
		if(!s->dynexport && s->dynimpname != nil)
			adduint16(d, SHN_UNDEF);
		else {
			switch(s->type) {
			default:
			case STEXT:
				t = 11;
				break;
			case SRODATA:
				t = 12;
				break;
			case SDATA:
				t = 13;
				break;
			case SBSS:
				t = 14;
				break;
			}
			adduint16(d, t);
		}
	
		/* value */
		if(s->type == SDYNIMPORT)
			adduint64(d, 0);
		else
			addaddr(d, s);
	
		/* size of object */
		adduint64(d, 0);
	
		if(!s->dynexport && s->dynimplib && needlib(s->dynimplib)) {
			elfwritedynent(lookup(".dynamic", 0), DT_NEEDED,
				addstring(lookup(".dynstr", 0), s->dynimplib));
		}
	} else if(HEADTYPE == Hdarwin) {
		// Mach-o symbol nlist64
		d = lookup(".dynsym", 0);
		name = s->dynimpname;
		if(name == nil)
			name = s->name;
		s->dynid = d->size/16;
		// darwin still puts _ prefixes on all C symbols
		str = lookup(".dynstr", 0);
		adduint32(d, str->size);
		adduint8(str, '_');
		addstring(str, name);
		if(s->type == SDYNIMPORT) {
			adduint8(d, 0x01);	// type - N_EXT - external symbol
			adduint8(d, 0);	// section
		} else {
			adduint8(d, 0x0f);
			switch(s->type) {
			default:
			case STEXT:
				adduint8(d, 1);
				break;
			case SDATA:
				adduint8(d, 2);
				break;
			case SBSS:
				adduint8(d, 4);
				break;
			}
		}
		adduint16(d, 0);	// desc
		if(s->type == SDYNIMPORT)
			adduint64(d, 0);	// value
		else
			addaddr(d, s);
	} else if(HEADTYPE != Hwindows) {
		diag("adddynsym: unsupported binary format");
	}
}
예제 #14
0
파일: obj.c 프로젝트: 29decibel/golang
void
main(int argc, char *argv[])
{
	char *p;
	Sym *s;

	Binit(&bso, 1, OWRITE);
	listinit();
	nerrors = 0;
	outfile = "5.out";
	HEADTYPE = -1;
	INITTEXT = -1;
	INITDAT = -1;
	INITRND = -1;
	INITENTRY = 0;
	linkmode = LinkAuto;
	nuxiinit();
	
	p = getgoarm();
	if(p != nil)
		goarm = atoi(p);
	else
		goarm = 6;
	if(goarm == 5)
		debug['F'] = 1;

	flagcount("1", "use alternate profiling code", &debug['1']);
	flagfn1("B", "info: define ELF NT_GNU_BUILD_ID note", addbuildinfo);
	flagstr("E", "sym: entry symbol", &INITENTRY);
	flagint32("D", "addr: data address", &INITDAT);
	flagcount("G", "debug pseudo-ops", &debug['G']);
	flagfn1("I", "interp: set ELF interp", setinterp);
	flagfn1("L", "dir: add dir to library path", Lflag);
	flagfn1("H", "head: header type", setheadtype);
	flagcount("K", "add stack underflow checks", &debug['K']);
	flagcount("M", "disable software div/mod", &debug['M']);
	flagcount("O", "print pc-line tables", &debug['O']);
	flagcount("P", "debug code generation", &debug['P']);
	flagint32("R", "rnd: address rounding", &INITRND);
	flagint32("T", "addr: text address", &INITTEXT);
	flagfn0("V", "print version and exit", doversion);
	flagcount("W", "disassemble input", &debug['W']);
	flagfn2("X", "name value: define string data", addstrdata);
	flagcount("Z", "clear stack frame on entry", &debug['Z']);
	flagcount("a", "disassemble output", &debug['a']);
	flagcount("c", "dump call graph", &debug['c']);
	flagcount("d", "disable dynamic executable", &debug['d']);
	flagstr("extld", "linker to run in external mode", &extld);
	flagstr("extldflags", "flags for external linker", &extldflags);
	flagcount("f", "ignore version mismatch", &debug['f']);
	flagcount("g", "disable go package data checks", &debug['g']);
	flagstr("k", "sym: set field tracking symbol", &tracksym);
	flagfn1("linkmode", "mode: set link mode (internal, external, auto)", setlinkmode);
	flagcount("n", "dump symbol table", &debug['n']);
	flagstr("o", "outfile: set output file", &outfile);
	flagcount("p", "insert profiling code", &debug['p']);
	flagstr("r", "dir1:dir2:...: set ELF dynamic linker search path", &rpath);
	flagcount("race", "enable race detector", &flag_race);
	flagcount("s", "disable symbol table", &debug['s']);
	flagcount("shared", "generate shared object (implies -linkmode external)", &flag_shared);
	flagstr("tmpdir", "leave temporary files in this directory", &tmpdir);
	flagcount("u", "reject unsafe packages", &debug['u']);
	flagcount("v", "print link trace", &debug['v']);
	flagcount("w", "disable DWARF generation", &debug['w']);
	
	flagparse(&argc, &argv, usage);

	if(argc != 1)
		usage();

	if(flag_shared)
		linkmode = LinkExternal;

	mywhatsys();

	if(HEADTYPE == -1)
		HEADTYPE = headtype(goos);

	// getgoextlinkenabled is based on GO_EXTLINK_ENABLED when
	// Go was built; see ../../make.bash.
	if(linkmode == LinkAuto && strcmp(getgoextlinkenabled(), "0") == 0)
		linkmode = LinkInternal;

	switch(HEADTYPE) {
	default:
		if(linkmode == LinkAuto)
			linkmode = LinkInternal;
		if(linkmode == LinkExternal && strcmp(getgoextlinkenabled(), "1") != 0)
			sysfatal("cannot use -linkmode=external with -H %s", headstr(HEADTYPE));
		break;
	case Hlinux:
		break;
	}

	libinit();

	switch(HEADTYPE) {
	default:
		diag("unknown -H option");
		errorexit();
	case Hnoheader:	/* no header */
		HEADR = 0L;
		if(INITTEXT == -1)
			INITTEXT = 0;
		if(INITDAT == -1)
			INITDAT = 0;
		if(INITRND == -1)
			INITRND = 4;
		break;
	case Hrisc:	/* aif for risc os */
		HEADR = 128L;
		if(INITTEXT == -1)
			INITTEXT = 0x10005000 + HEADR;
		if(INITDAT == -1)
			INITDAT = 0;
		if(INITRND == -1)
			INITRND = 4;
		break;
	case Hplan9x32:	/* plan 9 */
		HEADR = 32L;
		if(INITTEXT == -1)
			INITTEXT = 4128;
		if(INITDAT == -1)
			INITDAT = 0;
		if(INITRND == -1)
			INITRND = 4096;
		break;
	case Hixp1200: /* boot for IXP1200 */
		HEADR = 0L;
		if(INITTEXT == -1)
			INITTEXT = 0x0;
		if(INITDAT == -1)
			INITDAT = 0;
		if(INITRND == -1)
			INITRND = 4;
		break;
	case Hipaq: /* boot for ipaq */
		HEADR = 16L;
		if(INITTEXT == -1)
			INITTEXT = 0xC0008010;
		if(INITDAT == -1)
			INITDAT = 0;
		if(INITRND == -1)
			INITRND = 1024;
		break;
	case Hlinux:	/* arm elf */
	case Hfreebsd:
	case Hnetbsd:
		debug['d'] = 0;	// with dynamic linking
		tlsoffset = -8; // hardcoded number, first 4-byte word for g, and then 4-byte word for m
		                // this number is known to ../../pkg/runtime/rt0_*_arm.s
		elfinit();
		HEADR = ELFRESERVE;
		if(INITTEXT == -1)
			INITTEXT = 0x10000 + HEADR;
		if(INITDAT == -1)
			INITDAT = 0;
		if(INITRND == -1)
			INITRND = 4096;
		break;
	}
	if(INITDAT != 0 && INITRND != 0)
		print("warning: -D0x%ux is ignored because of -R0x%ux\n",
			INITDAT, INITRND);
	if(debug['v'])
		Bprint(&bso, "HEADER = -H0x%d -T0x%ux -D0x%ux -R0x%ux\n",
			HEADTYPE, INITTEXT, INITDAT, INITRND);
	Bflush(&bso);
	zprg.as = AGOK;
	zprg.scond = 14;
	zprg.reg = NREG;
	zprg.from.name = D_NONE;
	zprg.from.type = D_NONE;
	zprg.from.reg = NREG;
	zprg.to = zprg.from;
	buildop();
	histgen = 0;
	pc = 0;
	dtype = 4;

	version = 0;
	cbp = buf.cbuf;
	cbc = sizeof(buf.cbuf);

	// embed goarm to runtime.goarm
	s = lookup("runtime.goarm", 0);
	s->dupok = 1;
	adduint8(s, goarm);

	addlibpath("command line", "command line", argv[0], "main");
	loadlib();

	// mark some functions that are only referenced after linker code editing
	if(debug['F'])
		mark(rlookup("_sfloat", 0));
	mark(lookup("runtime.read_tls_fallback", 0));
	deadcode();
	if(textp == nil) {
		diag("no code");
		errorexit();
	}

	patch();
	if(debug['p'])
		if(debug['1'])
			doprof1();
		else
			doprof2();
	doelf();
	follow();
	softfloat();
	// 5l -Z means zero the stack frame on entry.
	// This slows down function calls but can help avoid
	// false positives in garbage collection.
	if(debug['Z'])
		dozerostk();
	noops(); // generate stack split prolog, handle div/mod, etc.
	dostkcheck();
	span();
	addexport();
	// textaddress() functionality is handled in span()
	pclntab();
	symtab();
	dodata();
	address();
	doweak();
	reloc();
	asmb();
	undef();
	hostlink();

	if(debug['c'])
		print("ARM size = %d\n", armsize);
	if(debug['v']) {
		Bprint(&bso, "%5.2f cpu time\n", cputime());
		Bprint(&bso, "%d sizeof adr\n", sizeof(Adr));
		Bprint(&bso, "%d sizeof prog\n", sizeof(Prog));
	}
	Bflush(&bso);
	errorexit();
}
예제 #15
0
파일: data.c 프로젝트: LEEWEN-DALIAN/golang
static void
proggenemit(ProgGen *g, uint8 v)
{
	adduint8(ctxt, g->s, v);
}