Example #1
0
func (b *Builder) link(out io.Writer, p *pkg, main string) error {
	var funcs []*link8.PkgSym

	addInit := func(p *pkg) {
		name := p.pkg.Init
		if name != "" && p.pkg.Lib.HasFunc(name) {
			funcs = append(funcs, &link8.PkgSym{p.path, name})
		}
	}

	for _, dep := range p.deps {
		addInit(b.pkgs[dep])
	}
	addInit(p)
	funcs = append(funcs, &link8.PkgSym{p.path, main})

	debugTable := debug8.NewTable()
	job := link8.NewJob(b.linkPkgs, funcs)
	job.InitPC = b.InitPC
	job.FuncDebug = func(pkg, name string, addr, size uint32) {
		debugTable.LinkFunc(b.debugFuncs, pkg, name, addr, size)
	}
	secs, err := job.Link()
	if err != nil {
		return err
	}

	debugSec, err := debugSection(debugTable)
	if err != nil {
		return err
	}
	secs = append(secs, debugSec)
	return e8.Write(out, secs)
}
Example #2
0
// LinkBareFunc produces a image of a single function that has no links.
func LinkBareFunc(f *Func) ([]byte, error) {
	if f.TooLarge() {
		return nil, fmt.Errorf("code section too large")
	}

	buf := new(bytes.Buffer)
	w := newWriter(make(map[string]*Pkg), buf)
	w.writeBareFunc(f)
	if err := w.Err(); err != nil {
		return nil, err
	}

	image := new(bytes.Buffer)
	sec := &e8.Section{
		Header: &e8.Header{
			Type: e8.Code,
			Addr: arch8.InitPC,
		},
		Bytes: buf.Bytes(),
	}
	if err := e8.Write(image, []*e8.Section{sec}); err != nil {
		return nil, err
	}

	return image.Bytes(), nil
}
Example #3
0
// BuildSingleFile builds a package named "main" from a single file.
func BuildSingleFile(f string, rc io.ReadCloser) ([]byte, []*lex8.Error) {
	path := "_"

	pinfo := build8.SimplePkg(path, f, rc)

	pkg, errs := Lang().Compile(pinfo, new(build8.Options))
	if errs != nil {
		return nil, errs
	}

	secs, err := link8.LinkSinglePkg(pkg.Lib, pkg.Main)
	if err != nil {
		return nil, lex8.SingleErr(err)
	}

	buf := new(bytes.Buffer)
	if err := e8.Write(buf, secs); err != nil {
		return nil, lex8.SingleErr(err)
	}
	return buf.Bytes(), nil
}