Esempio n. 1
0
func gentext() {
	if !ld.DynlinkingGo() {
		return
	}
	addmoduledata := ld.Linklookup(ld.Ctxt, "runtime.addmoduledata", 0)
	if addmoduledata.Type == ld.STEXT {
		// we're linking a module containing the runtime -> no need for
		// an init function
		return
	}
	addmoduledata.Reachable = true
	initfunc := ld.Linklookup(ld.Ctxt, "go.link.addmoduledata", 0)
	initfunc.Type = ld.STEXT
	initfunc.Local = true
	initfunc.Reachable = true
	o := func(op ...uint8) {
		for _, op1 := range op {
			ld.Adduint8(ld.Ctxt, initfunc, op1)
		}
	}
	// 0000000000000000 <local.dso_init>:
	//    0:	48 8d 3d 00 00 00 00 	lea    0x0(%rip),%rdi        # 7 <local.dso_init+0x7>
	// 			3: R_X86_64_PC32	runtime.firstmoduledata-0x4
	o(0x48, 0x8d, 0x3d)
	ld.Addpcrelplus(ld.Ctxt, initfunc, ld.Linklookup(ld.Ctxt, "runtime.firstmoduledata", 0), 0)
	//    7:	e8 00 00 00 00       	callq  c <local.dso_init+0xc>
	// 			8: R_X86_64_PLT32	runtime.addmoduledata-0x4
	o(0xe8)
	Addcall(ld.Ctxt, initfunc, addmoduledata)
	//    c:	c3                   	retq
	o(0xc3)
	if ld.Ctxt.Etextp != nil {
		ld.Ctxt.Etextp.Next = initfunc
	} else {
		ld.Ctxt.Textp = initfunc
	}
	ld.Ctxt.Etextp = initfunc
	initarray_entry := ld.Linklookup(ld.Ctxt, "go.link.addmoduledatainit", 0)
	initarray_entry.Reachable = true
	initarray_entry.Local = true
	initarray_entry.Type = ld.SINITARR
	ld.Addaddr(ld.Ctxt, initarray_entry, initfunc)
}
Esempio n. 2
0
func elfreloc1(r *ld.Reloc, sectoff int64) int {
	ld.Thearch.Vput(uint64(sectoff))

	elfsym := r.Xsym.Elfsym
	switch r.Type {
	default:
		return -1

	case ld.R_ADDR:
		if r.Siz == 4 {
			ld.Thearch.Vput(ld.R_X86_64_32 | uint64(elfsym)<<32)
		} else if r.Siz == 8 {
			ld.Thearch.Vput(ld.R_X86_64_64 | uint64(elfsym)<<32)
		} else {
			return -1
		}

	case ld.R_TLS_LE:
		if r.Siz == 4 {
			ld.Thearch.Vput(ld.R_X86_64_TPOFF32 | uint64(elfsym)<<32)
		} else {
			return -1
		}

	case ld.R_TLS_IE:
		if r.Siz == 4 {
			ld.Thearch.Vput(ld.R_X86_64_GOTTPOFF | uint64(elfsym)<<32)
		} else {
			return -1
		}

	case ld.R_CALL:
		if r.Siz == 4 {
			if r.Xsym.Type == ld.SDYNIMPORT {
				if ld.DynlinkingGo() {
					ld.Thearch.Vput(ld.R_X86_64_PLT32 | uint64(elfsym)<<32)
				} else {
					ld.Thearch.Vput(ld.R_X86_64_GOTPCREL | uint64(elfsym)<<32)
				}
			} else {
				ld.Thearch.Vput(ld.R_X86_64_PC32 | uint64(elfsym)<<32)
			}
		} else {
			return -1
		}

	case ld.R_PCREL:
		if r.Siz == 4 {
			ld.Thearch.Vput(ld.R_X86_64_PC32 | uint64(elfsym)<<32)
		} else {
			return -1
		}

	case ld.R_GOTPCREL:
		if r.Siz == 4 {
			ld.Thearch.Vput(ld.R_X86_64_GOTPCREL | uint64(elfsym)<<32)
		} else {
			return -1
		}

	case ld.R_TLS:
		if r.Siz == 4 {
			if ld.Buildmode == ld.BuildmodeCShared {
				ld.Thearch.Vput(ld.R_X86_64_GOTTPOFF | uint64(elfsym)<<32)
			} else {
				ld.Thearch.Vput(ld.R_X86_64_TPOFF32 | uint64(elfsym)<<32)
			}
		} else {
			return -1
		}
	}

	ld.Thearch.Vput(uint64(r.Xadd))
	return 0
}
Esempio n. 3
0
func archinit() {
	// getgoextlinkenabled is based on GO_EXTLINK_ENABLED when
	// Go was built; see ../../make.bash.
	if ld.Linkmode == ld.LinkAuto && obj.Getgoextlinkenabled() == "0" {
		ld.Linkmode = ld.LinkInternal
	}

	if ld.Buildmode == ld.BuildmodeCShared || ld.DynlinkingGo() {
		ld.Linkmode = ld.LinkExternal
	}

	switch ld.HEADTYPE {
	default:
		if ld.Linkmode == ld.LinkAuto {
			ld.Linkmode = ld.LinkInternal
		}
		if ld.Linkmode == ld.LinkExternal && obj.Getgoextlinkenabled() != "1" {
			log.Fatalf("cannot use -linkmode=external with -H %s", ld.Headstr(int(ld.HEADTYPE)))
		}

	case ld.Hdarwin,
		ld.Hdragonfly,
		ld.Hfreebsd,
		ld.Hlinux,
		ld.Hnacl,
		ld.Hnetbsd,
		ld.Hopenbsd,
		ld.Hsolaris,
		ld.Hwindows:
		break
	}

	switch ld.HEADTYPE {
	default:
		ld.Diag("unknown -H option")
		ld.Errorexit()
		fallthrough

	case ld.Hplan9: /* plan 9 */
		ld.HEADR = 32 + 8

		if ld.INITTEXT == -1 {
			ld.INITTEXT = 0x200000 + int64(ld.HEADR)
		}
		if ld.INITDAT == -1 {
			ld.INITDAT = 0
		}
		if ld.INITRND == -1 {
			ld.INITRND = 0x200000
		}

	case ld.Helf: /* elf32 executable */
		ld.HEADR = int32(ld.Rnd(52+3*32, 16))

		if ld.INITTEXT == -1 {
			ld.INITTEXT = 0x80110000
		}
		if ld.INITDAT == -1 {
			ld.INITDAT = 0
		}
		if ld.INITRND == -1 {
			ld.INITRND = 4096
		}

	case ld.Hdarwin: /* apple MACH */
		ld.Machoinit()

		ld.HEADR = ld.INITIAL_MACHO_HEADR
		if ld.INITRND == -1 {
			ld.INITRND = 4096
		}
		if ld.INITTEXT == -1 {
			ld.INITTEXT = 4096 + int64(ld.HEADR)
		}
		if ld.INITDAT == -1 {
			ld.INITDAT = 0
		}

	case ld.Hlinux, /* elf64 executable */
		ld.Hfreebsd,   /* freebsd */
		ld.Hnetbsd,    /* netbsd */
		ld.Hopenbsd,   /* openbsd */
		ld.Hdragonfly, /* dragonfly */
		ld.Hsolaris:   /* solaris */
		ld.Elfinit()

		ld.HEADR = ld.ELFRESERVE
		if ld.INITTEXT == -1 {
			ld.INITTEXT = (1 << 22) + int64(ld.HEADR)
		}
		if ld.INITDAT == -1 {
			ld.INITDAT = 0
		}
		if ld.INITRND == -1 {
			ld.INITRND = 4096
		}

	case ld.Hnacl:
		ld.Elfinit()
		ld.Debug['w']++ // disable dwarf, which gets confused and is useless anyway
		ld.HEADR = 0x10000
		ld.Funcalign = 32
		if ld.INITTEXT == -1 {
			ld.INITTEXT = 0x20000
		}
		if ld.INITDAT == -1 {
			ld.INITDAT = 0
		}
		if ld.INITRND == -1 {
			ld.INITRND = 0x10000
		}

	case ld.Hwindows: /* PE executable */
		ld.Peinit()

		ld.HEADR = ld.PEFILEHEADR
		if ld.INITTEXT == -1 {
			ld.INITTEXT = ld.PEBASE + int64(ld.PESECTHEADR)
		}
		if ld.INITDAT == -1 {
			ld.INITDAT = 0
		}
		if ld.INITRND == -1 {
			ld.INITRND = ld.PESECTALIGN
		}
	}

	if ld.INITDAT != 0 && ld.INITRND != 0 {
		fmt.Printf("warning: -D0x%x is ignored because of -R0x%x\n", uint64(ld.INITDAT), uint32(ld.INITRND))
	}
}