49 lines
No EOL
1 KiB
Go
49 lines
No EOL
1 KiB
Go
package linker
|
|
|
|
import (
|
|
"os"
|
|
|
|
"git.urbach.dev/cli/q/src/asm"
|
|
"git.urbach.dev/cli/q/src/build"
|
|
"git.urbach.dev/cli/q/src/core"
|
|
"git.urbach.dev/cli/q/src/data"
|
|
"git.urbach.dev/cli/q/src/elf"
|
|
)
|
|
|
|
// WriteFile writes an executable file to disk.
|
|
func WriteFile(executable string, b *build.Build, env *core.Environment) error {
|
|
file, err := os.Create(executable)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
init := env.Functions["core.init"]
|
|
traversed := make(map[*core.Function]bool, len(env.Functions))
|
|
|
|
final := asm.Assembler{
|
|
Instructions: make([]asm.Instruction, 0, 32),
|
|
Data: make(data.Data, 32),
|
|
}
|
|
|
|
// This will place the main function immediately after the entry point
|
|
// and also add everything the main function calls recursively.
|
|
init.EachDependency(traversed, func(f *core.Function) {
|
|
final.Merge(&f.Assembler)
|
|
})
|
|
|
|
code, data := final.Compile(b)
|
|
|
|
switch b.OS {
|
|
case build.Linux:
|
|
elf.Write(file, b, code, data)
|
|
}
|
|
|
|
err = file.Close()
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return os.Chmod(executable, 0755)
|
|
} |