예제 #1
0
파일: usb.go 프로젝트: ftrvxmtrx/build
func (s *USB) Build(c *build.Context) error {
	f, err := c.Open(s.Conf)
	if err != nil {
		return err
	}
	buf, err := ioutil.ReadAll(f)
	if err != nil {
		log.Fatal(err)
	}

	var sysconf SysConf
	err = json.Unmarshal(buf, &sysconf)
	if err != nil {
		return err
	}
	fileOut := fmt.Sprintf("%s.c", s.Name)
	out, err := c.Create(fileOut)
	if err != nil {
		return err
	}
	tmpl, err := template.New("usbdb.c").Parse(jtab)
	err = tmpl.Execute(out, sysconf.Embeds)
	if err != nil {
		return err
	}
	return nil
}
예제 #2
0
파일: data2c.go 프로젝트: ftrvxmtrx/build
func (dtc *DataToC) Build(c *build.Context) error {

	inFile, err := c.Open(dtc.Bin)
	if err != nil {
		return err
	}

	in, err := ioutil.ReadAll(inFile)
	if err != nil {
		return err
	}

	total := len(in)
	out, err := c.Create(fmt.Sprintf("%s.c", dtc.Name))

	if err != nil {
		return err
	}

	fmt.Fprintf(out, "unsigned char %vcode[] = {\n", dtc.Prefix)
	for len(in) > 0 {
		for j := 0; j < 16 && len(in) > 0; j++ {
			fmt.Fprintf(out, "0x%02x, ", in[0])
			in = in[1:]
		}
		fmt.Fprintf(out, "\n")

	}

	fmt.Fprintf(out, "0,\n};\nint %vlen = %v;\n", dtc.Prefix, total)
	return nil
}
예제 #3
0
파일: config.go 프로젝트: ftrvxmtrx/build
// data2c takes the file at path and creates a C byte array containing it.
func data2c(name string, path string, c *build.Context) (string, error) {
	var out []byte
	var in []byte
	var file *os.File
	var err error
	if file, err = c.Open(path); err != nil {
		return "", fmt.Errorf("open :%s", err.Error())

	}

	if in, err = ioutil.ReadAll(file); err != nil {
		return "", nil
	}

	file.Close()

	total := len(in)

	out = []byte(fmt.Sprintf("static unsigned char ramfs_%s_code[] = {\n", name))
	for len(in) > 0 {
		for j := 0; j < 16 && len(in) > 0; j++ {
			out = append(out, []byte(fmt.Sprintf("0x%02x, ", in[0]))...)
			in = in[1:]
		}
		out = append(out, '\n')
	}

	out = append(out, []byte(fmt.Sprintf("0,\n};\nint ramfs_%s_len = %v;\n", name, total))...)

	return string(out), nil
}
예제 #4
0
파일: strip.go 프로젝트: ftrvxmtrx/build
func (s *Strip) Build(c *build.Context) error {
	params := []string{"-o"}
	params = append(params, s.Name)
	params = append(params, filepath.Join("bin", split(s.Dependencies[0], ":")))
	if err := c.Exec(Stripper(), nil, params); err != nil {
		return fmt.Errorf(err.Error())
	}
	return nil
}
예제 #5
0
파일: genrule.go 프로젝트: ftrvxmtrx/build
func (g *GenRule) Build(c *build.Context) error {
	for _, cmd := range g.Commands {
		strs := strings.Split(cmd, " ")

		if err := c.Exec(strs[0], nil, strs[1:]); err != nil {
			c.Println(err.Error())
			return err
		}
	}
	return nil
}
예제 #6
0
파일: objcopy.go 프로젝트: ftrvxmtrx/build
func (oc *ObjCopy) Build(c *build.Context) error {
	params := []string{}
	params = append(params, "-I")
	params = append(params, oc.In)
	params = append(params, "-O")
	params = append(params, oc.Out)
	params = append(params, filepath.Join("bin", split(oc.Dependencies[0], ":")))
	params = append(params, oc.Name)
	if err := c.Exec(Copier(), nil, params); err != nil {
		return fmt.Errorf(err.Error())
	}
	return nil
}
예제 #7
0
파일: clib.go 프로젝트: ftrvxmtrx/build
func (cl *CLib) Build(c *build.Context) error {
	params := []string{"-c"}
	params = append(params, cl.CompilerOptions...)
	params = append(params, cl.LinkerOptions...)
	params = append(params, cl.Sources...)
	params = append(params, cl.Includes.Includes()...)

	if err := c.Exec(Compiler(), CCENV, params); err != nil {
		c.Println(err.Error())
		return fmt.Errorf(cl.buf.String())
	}

	libName := fmt.Sprintf("%s.a", cl.Name)
	params = []string{"-rs", libName}
	params = append(params, cl.LinkerOptions...)
	// This is done under the assumption that each src file put in this thing
	// here will comeout as a .o file
	for _, f := range cl.Sources {
		_, filename := filepath.Split(f)
		params = append(params, fmt.Sprintf("%s.o", filename[:strings.LastIndex(filename, ".")]))
	}

	if err := c.Exec(Archiver(), CCENV, params); err != nil {
		c.Println(err.Error())
		return fmt.Errorf(cl.buf.String())
	}

	return nil
}
예제 #8
0
파일: man.go 프로젝트: ftrvxmtrx/build
func (mp *ManPage) Build(c *build.Context) error {
	for _, m := range mp.Sources {
		params := []string{"<"}
		params = append(params, m)

		params = append(params, ">")
		params = append(params, fmt.Sprintf("%s.html", m))

		c.Println(strings.Join(append([]string{"man2html"}, params...), " "))

		if err := c.Exec("man2html", nil, params); err != nil {
			return err
		}
	}
	return nil
}
예제 #9
0
파일: sed.go 프로젝트: ftrvxmtrx/build
func (s *Sed) Build(c *build.Context) error {
	params := s.Args
	params = append(params, s.File)
	out, err := exec.Command("sed", params...).Output()
	if err != nil {
		return err
	}
	f, err := c.Create(s.Name)
	if err != nil {
		return err
	}
	io.WriteString(f, "#!/bin/rc")
	io.WriteString(f, "# THIS FILE IS AUTOMATICALLY GENERATED'")
	io.WriteString(f, fmt.Sprintf("# FROM %S  DO NOT EDIT.", s.File))
	f.Write(out)
	return nil
}
예제 #10
0
파일: config.go 프로젝트: ftrvxmtrx/build
func (k *Config) Build(c *build.Context) error {

	var rootcodes []string
	var rootnames []string
	for _, dep := range k.Dependencies {
		name := split(dep, ":")
		code, err := data2c(name, filepath.Join("bin", name), c)

		if err != nil {
			return err
		}
		rootcodes = append(rootcodes, code)
		rootnames = append(rootnames, name)
	}
	for _, p := range k.RamFiles {
		name := filepath.Base(p)
		code, err := data2c(name, p, c)

		if err != nil {
			return err
		}
		rootcodes = append(rootcodes, code)
		rootnames = append(rootnames, name)
	}
	path := fmt.Sprintf("%s.c", k.Name)
	vars := struct {
		Path      string
		Config    Config
		Rootnames []string
		Rootcodes []string
	}{
		path,
		*k,
		rootnames,
		rootcodes,
	}
	tmpl := template.Must(template.New("kernconf").Parse(kernconfTmpl))
	f, err := c.Create(path)
	if err != nil {
		return nil
	}
	return tmpl.Execute(f, vars)

}
예제 #11
0
파일: yacc.go 프로젝트: ftrvxmtrx/build
func (y *Yacc) Build(c *build.Context) error {

	params := []string{}
	params = append(params, y.YaccOptions...)
	params = append(params, y.Sources...)

	c.Println(strings.Join(append([]string{"yacc"}, params...), " "))

	if err := c.Exec("yacc", nil, params); err != nil {
		c.Println(err.Error())
		return fmt.Errorf(y.buf.String())
	}

	return nil
}
예제 #12
0
파일: npm.go 프로젝트: ftrvxmtrx/build
func (npm *NpmPackage) Build(c *build.Context) error {
	if npm.Version == "" {
		return fmt.Errorf("NPM package %s failed to install, no version string")
	}

	params := []string{}
	params = append(params, "install")

	params = append(params, fmt.Sprintf("%s@%s", npm.Name, npm.Version))
	c.Println(strings.Join(append([]string{"npm"}, params...), " "))

	if err := c.Exec("npm", nil, params); err != nil {
		c.Println(err.Error())
		return fmt.Errorf(err.Error())
	}
	return nil
}
예제 #13
0
파일: cbin.go 프로젝트: ftrvxmtrx/build
func (cb *CBin) Build(c *build.Context) error {
	c.Println(prettyprint.AsJSON(cb))
	params := []string{}
	params = append(params, cb.CompilerOptions...)
	params = append(params, cb.Sources...)

	params = append(params, cb.Includes.Includes()...)

	if err := c.Exec(Compiler(), CCENV, params); err != nil {
		return fmt.Errorf(err.Error())
	}

	ldparams := []string{"-o", cb.Name}
	ldparams = append(ldparams, cb.LinkerOptions...)
	if cb.LinkerFile != "" {
		ldparams = append(ldparams, cb.LinkerFile)
	}
	// This is done under the assumption that each src file put in this thing
	// here will comeout as a .o file
	for _, f := range cb.Sources {
		_, fname := filepath.Split(f)
		ldparams = append(ldparams, fmt.Sprintf("%s.o", fname[:strings.LastIndex(fname, ".")]))
	}

	ldparams = append(ldparams, "-L", "lib")

	for _, dep := range cb.Dependencies {
		d := split(dep, ":")
		if len(d) < 3 {
			continue
		}
		if d[:3] == "lib" {
			ldparams = append(ldparams, fmt.Sprintf("-l%s", d[3:]))
		}
	}

	if err := c.Exec(Linker(), CCENV, ldparams); err != nil {
		return fmt.Errorf(err.Error())
	}

	return nil
}
예제 #14
0
파일: mksys.go 프로젝트: ftrvxmtrx/build
func (mkSys *MkSys) Build(c *build.Context) error {

	c.Println(prettyprint.AsJSON(mkSys))

	sysconf, err := mkSys.readSysconf()
	if err != nil {
		return err
	}

	syscalls := sysconf.Syscalls
	syserrors := sysconf.Syserrors
	bootmethods := sysconf.Bootmethods
	for i := range syscalls {
		if syscalls[i].Define == "" {
			syscalls[i].Define = strings.ToUpper(syscalls[i].Name)
		}
		if syscalls[i].Sysname == "" {
			syscalls[i].Sysname = "sys" + syscalls[i].Name
		}
		if syscalls[i].Libname == "" {
			syscalls[i].Libname = syscalls[i].Name
		}
	}

	outfile, err := c.Create(mkSys.Mode)
	if err != nil {
		return err
	}
	switch mkSys.Mode {
	case "sys_harvey.s":
		if mkSys.ARCH != "amd64" {
			c.Println("ARCH unsupported or not set")
		}
		syscallargs := []string{"DI", "SI", "DX", "R10", "R8", "R9"}
		//funcallregs := []string{ "DI", "SI", "DX", "CX", "R8", "R9" };
		for i := range syscalls {
			goargs := []string{}
			fpoff := 0
			for k := range syscalls[i].Args {
				switch syscalls[i].Args[k] {
				case "int32_t", "uint32_t":
					goargs = append(goargs, fmt.Sprintf("MOVL	arg%d+%d(FP), %s", k, fpoff, syscallargs[k]))
					fpoff += 4
				case "void*", "char*", "char**", "uint8_t*", "int32_t*", "uint64_t*", "int64_t*", "int64_t":
					fpoff = (fpoff + 7) & ^7
					goargs = append(goargs, fmt.Sprintf("MOVQ	arg%d+%d(FP), %s", k, fpoff, syscallargs[k]))
					fpoff += 8
				default:
					return fmt.Errorf("unsupported arg %s in syscall: %v", syscalls[i].Args[k], syscalls[i])
				}
			}
			syscalls[i].GoArgs = goargs
			switch syscalls[i].Ret[0] {
			case "int32_t", "uint32_t":
				syscalls[i].Ret0 = fmt.Sprintf("MOVL	AX, ret+%d(FP)", fpoff)
				fpoff += 4
			case "void*", "char*", "char**", "uint8_t*", "int32_t*", "uint64_t*", "int64_t*", "int64_t":
				fpoff = (fpoff + 7) & ^7
				syscalls[i].Ret0 = fmt.Sprintf("MOVQ	AX, ret+%d(FP)", fpoff)
				fpoff += 8
			default:
				return fmt.Errorf("unsupported Ret[0] in syscall: %v", syscalls[i])
			}
		}
		tmpl, err := template.New("sys_harvey.s").Parse(`/* automatically generated by mksys */
/* System calls for AMD64, Harvey */
#include "go_asm.h"
#include "go_tls.h"
#include "textflag.h"
{{ range . }}
TEXT runtime·{{ .Libname }}(SB),NOSPLIT,$0
{{ range .GoArgs }}	{{ . }}
{{ end }}	MOVQ	${{ .Id }}, AX
	SYSCALL
	{{ .Ret0 }}
	RET
{{ end }}
`)
		if err != nil {
			return err
		}
		err = tmpl.Execute(outfile, syscalls)
		if err != nil {
			return err
		}

	case "syscallfiles":
		if mkSys.ARCH != "amd64" {
			return fmt.Errorf("ARCH unsupported or not set")
		}
		tmpl, err := template.New("syscall.s").Parse(`/* automatically generated by mksys */
.globl	{{ .Libname }}
{{ .Libname }}:
	movq %rcx, %r10 /* rcx gets smashed by systenter. Use r10.*/
	movq ${{ .Id }},%rax  /* Put the system call into rax, just like linux. */
	syscall
	ret
`)
		if err != nil {
			return err
		}

		for i := range syscalls {

			file, err := c.Create(syscalls[i].Libname + ".s")
			if err != nil {
				return err
			}

			err = tmpl.Execute(file, syscalls[i])
			if err != nil {
				return err
			}

			err = file.Close()
			if err != nil {
				return err
			}
		}
	case "sysnum.go":
		tmpl, err := template.New("sysnum.go").Parse(`// automatically generated by mksys
package syscall
const(
{{ range . }}	SYS_{{ .Define }} = {{ .Id }}
{{ end }}
)
`)
		err = tmpl.Execute(outfile, syscalls)
		if err != nil {
			return err
		}

	case "sys.h":
		tmpl, err := template.New("sys.h").Parse(`/* automatically generated by mksys */
{{ range . }}#define {{ .Define }} {{ .Id }}
{{ end }}
`)
		err = tmpl.Execute(outfile, syscalls)
		if err != nil {
			return err
		}

	case "sysdecl.h":
		tmpl, err := template.New("sysdecl.h").Parse(`/* automatically generated by mksys */
{{ range . }}extern {{ .Ret0 }} {{ .Libname }}({{ range $i, $e := .Args }}{{ if $i }}, {{ end }}{{ $e }}{{ end }});
{{ end }}
`)
		err = tmpl.Execute(outfile, syscalls)
		if err != nil {
			return err
		}

	case "systab.c":
		for i := range syscalls {
			var fudge string
			switch syscalls[i].Ret[0] {
			case "int32_t":
				fudge = "{ .i = -1 }"
			case "int64_t":
				fudge = "{ .vl = -1ll }"
			case "void*", "char*":
				fudge = "{ .v = (void*)-1ll }"
			default:
				return fmt.Errorf("unsupported Ret[0] in syscall: %v", syscalls[i])
			}
			if syscalls[i].Fudge == "" {
				syscalls[i].Fudge = fudge
			}

			syscalls[i].Ret0 = syscalls[i].Ret[0]
		}
		tmpl, err := template.New("systab.c").Parse(`/* automatically generated by mksys */
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include <sys.h>
{{ range . }}extern void {{ .Sysname }}(Ar0*, ...);
{{ end }}
Systab systab[] = {
{{ range . }}[{{ .Define }}] { "{{ .Name }}", {{ .Sysname }}, {{ .Fudge }} },
{{ end }}
};
int nsyscall = nelem(systab);
`)
		err = tmpl.Execute(outfile, syscalls)
		if err != nil {
			return err
		}

	case "error.h":
		tmpl, err := template.New("error.h").Parse(`/* automatically generated by mksys */
{{ range . }}extern char {{ .Name }}[]; /* {{ .String }} */
{{ end }}
`)
		err = tmpl.Execute(outfile, syserrors)
		if err != nil {
			return err
		}

	case "errstr.h":
		tmpl, err := template.New("errstr.h").Parse(`/* automatically generated by mksys */
{{ range . }}char {{ .Name }}[] = "{{ .String }}";
{{ end }}
`)
		err = tmpl.Execute(outfile, syserrors)
		if err != nil {
			return err
		}
	case "bootamd64cpu.c":
		tmpl, err := template.New("bootamd64cpu.c").Parse(`/* automatically generated by mksys */
#include <u.h>
#include <libc.h>
#include <boot.h>
Method method[] = {
{{ range . }}{ "{{.Name}}", {{.Config}}, {{.Connect}}, "{{.Arg}}", },
{{ end }}
	{ nil },
};
int cpuflag = 1;
char* rootdir = "/root";
char* bootdisk = "#S/sdE0/";
extern void boot(int, char**);
void
main(int argc, char **argv)
{
		boot(argc, argv);
}
int (*cfs)(int) = 0;
`)
		err = tmpl.Execute(outfile, bootmethods)
		if err != nil {
			log.Fatal(err)
		}
	}
	return nil
}
예제 #15
0
파일: elf2c.go 프로젝트: ftrvxmtrx/build
func (etc *ElfToC) Build(c *build.Context) error {
	fileName := ""

	if xf, err := c.Open(etc.Elf); err != nil {
		return fmt.Errorf("open :%s", err.Error())
	} else {
		fileName = xf.Name()
		xf.Close()
	}

	f, err := elf.Open(fileName)
	if err != nil {
		return err
	}
	var dataend, codeend, end uint64
	var datastart, codestart, start uint64
	datastart, codestart, start = math.MaxUint64, math.MaxUint64, math.MaxUint64
	mem := []byte{}
	for _, v := range f.Progs {
		if v.Type != elf.PT_LOAD {
			continue
		}
		c.Printf("processing %v\n", v)
		// MUST alignt to 2M page boundary.
		// then MUST allocate a []byte that
		// is the right size. And MUST
		// see if by some off chance it
		// joins to a pre-existing segment.
		// It's easier than it seems. We produce ONE text
		// array and ONE data array. So it's a matter of creating
		// a virtual memory space with an assumed starting point of
		// 0x200000, and filling it. We just grow that as needed.

		curstart := v.Vaddr & ^uint64(0xfff) // 0x1fffff)
		curend := v.Vaddr + v.Memsz
		c.Printf("s %x e %x\n", curstart, curend)
		if curend > end {
			nmem := make([]byte, curend)
			copy(nmem, mem)
			mem = nmem
		}
		if curstart < start {
			start = curstart
		}

		if v.Flags&elf.PF_X == elf.PF_X {
			if curstart < codestart {
				codestart = curstart
			}
			if curend > codeend {
				codeend = curend
			}
			c.Printf("code s %v e %v\n", codestart, codeend)
		} else {
			if curstart < datastart {
				datastart = curstart
			}
			if curend > dataend {
				dataend = curend
			}
			c.Printf("data s %v e %v\n", datastart, dataend)
		}
		for i := uint64(0); i < v.Filesz; i++ {
			if amt, err := v.ReadAt(mem[v.Vaddr+i:], int64(i)); err != nil && err != io.EOF {
				err := fmt.Errorf("%v: %v\n", amt, err)
				c.Println(err)
				return err
			} else if amt == 0 {
				if i < v.Filesz {
					err := fmt.Errorf("%v: Short read: %v of %v\n", v, i, v.Filesz)
					c.Println(err)
					return err
				}
				break
			} else {
				i = i + uint64(amt)
				c.Printf("i now %d\n", i)
			}
		}
		c.Printf("Processed %v\n", v)
	}
	c.Printf("gencode\n")
	// Gen code to stdout. For each file, create an array, a start, and an end variable.
	outfile, err := c.Create(fmt.Sprintf("%s.h", etc.Name))
	if err != nil {
		return err
	}

	_, file := path.Split(etc.Elf)

	gencode(outfile, file, "code", mem, codestart, codeend)
	gencode(outfile, file, "data", mem, datastart, dataend)

	return nil
}