package linker import ( "io" "git.urbach.dev/cli/q/src/asm" "git.urbach.dev/cli/q/src/config" "git.urbach.dev/cli/q/src/core" "git.urbach.dev/cli/q/src/data" "git.urbach.dev/cli/q/src/elf" "git.urbach.dev/cli/q/src/macho" "git.urbach.dev/cli/q/src/pe" ) // Write writes an executable to the given writer. func Write(writer io.WriteSeeker, env *core.Environment) { program := asm.Assembler{ Instructions: make([]asm.Instruction, 0, 256), Data: data.Data{ Immutable: make(map[string][]byte, 16), Mutable: make(map[string][]byte, 16), }, } initTLS(&program, env) for f := range env.LiveFunctions() { program.Merge(&f.Assembler) } build := env.Build code, data, libs, labels := program.Compile(build) switch build.OS { case config.Linux: functions := make(map[string]int, 32) for f := range env.LiveFunctions() { functions[f.FullName] = labels[f.FullName] } elf.Write(writer, build, code, data, functions) case config.Mac: macho.Write(writer, build, code, data, libs) case config.Windows: pe.Write(writer, build, code, data, libs) } }