diff --git a/src/arm64/Registers.go b/src/arm64/Registers.go index 088e2b3..7cee1b7 100644 --- a/src/arm64/Registers.go +++ b/src/arm64/Registers.go @@ -37,4 +37,8 @@ const ( SP // Stack pointer ) -var SyscallInputRegisters = []cpu.Register{X8, X0, X1, X2, X3, X4, X5} +var ( + SyscallInputRegisters = []cpu.Register{X8, X0, X1, X2, X3, X4, X5} + WindowsInputRegisters = []cpu.Register{X0, X1, X2, X3, X4, X5, X6, X7} + WindowsOutputRegisters = []cpu.Register{X0, X1} +) diff --git a/src/asm/Finalize.go b/src/asm/Finalize.go index 3ae543a..b8a2622 100644 --- a/src/asm/Finalize.go +++ b/src/asm/Finalize.go @@ -8,7 +8,7 @@ import ( "git.akyoto.dev/cli/q/src/config" "git.akyoto.dev/cli/q/src/dll" - "git.akyoto.dev/cli/q/src/exe" + "git.akyoto.dev/cli/q/src/fs" "git.akyoto.dev/cli/q/src/sizeof" "git.akyoto.dev/cli/q/src/x64" ) @@ -372,7 +372,7 @@ restart: data, dataLabels = a.Data.Finalize() dataStart := config.BaseAddress + config.CodeOffset + len(code) - dataStart, _ = exe.Align(dataStart, config.Align) + dataStart, _ = fs.Align(dataStart, config.Align) for _, pointer := range dataPointers { address := Address(dataStart) + pointer.Resolve() diff --git a/src/linux/Syscall.go b/src/compiler/Linux.go similarity index 71% rename from src/linux/Syscall.go rename to src/compiler/Linux.go index 82eb953..9a12592 100644 --- a/src/linux/Syscall.go +++ b/src/compiler/Linux.go @@ -1,7 +1,7 @@ -package linux +package compiler // https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/x86/entry/syscalls/syscall_64.tbl const ( - Write = 1 - Exit = 60 + LinuxWrite = 1 + LinuxExit = 60 ) diff --git a/src/mac/Syscall.go b/src/compiler/Mac.go similarity index 63% rename from src/mac/Syscall.go rename to src/compiler/Mac.go index 2111c25..b1fac49 100644 --- a/src/mac/Syscall.go +++ b/src/compiler/Mac.go @@ -1,10 +1,10 @@ -package mac +package compiler // Syscall numbers are divided into classes, here we need the BSD inherited syscalls. -const SyscallClassUnix = 0x2000000 +const classUnix = 0x2000000 // https://github.com/apple-oss-distributions/xnu/blob/main/bsd/kern/syscalls.master const ( - Exit = 1 | SyscallClassUnix - Write = 4 | SyscallClassUnix + MacExit = 1 | classUnix + MacWrite = 4 | classUnix ) diff --git a/src/compiler/Result.go b/src/compiler/Result.go index 7343241..5186858 100644 --- a/src/compiler/Result.go +++ b/src/compiler/Result.go @@ -11,11 +11,8 @@ import ( "git.akyoto.dev/cli/q/src/core" "git.akyoto.dev/cli/q/src/dll" "git.akyoto.dev/cli/q/src/elf" - "git.akyoto.dev/cli/q/src/linux" - "git.akyoto.dev/cli/q/src/mac" "git.akyoto.dev/cli/q/src/macho" "git.akyoto.dev/cli/q/src/pe" - "git.akyoto.dev/cli/q/src/windows" "git.akyoto.dev/cli/q/src/x64" ) @@ -42,15 +39,15 @@ func (r *Result) finalize() ([]byte, []byte, dll.List) { switch config.TargetOS { case "linux": - final.RegisterNumber(asm.MOVE, x64.SyscallInputRegisters[0], linux.Exit) + final.RegisterNumber(asm.MOVE, x64.SyscallInputRegisters[0], LinuxExit) final.RegisterNumber(asm.MOVE, x64.SyscallInputRegisters[1], 0) final.Syscall() case "mac": - final.RegisterNumber(asm.MOVE, x64.SyscallInputRegisters[0], mac.Exit) + final.RegisterNumber(asm.MOVE, x64.SyscallInputRegisters[0], MacExit) final.RegisterNumber(asm.MOVE, x64.SyscallInputRegisters[1], 0) final.Syscall() case "windows": - final.RegisterNumber(asm.MOVE, windows.X64InputRegisters[0], 0) + final.RegisterNumber(asm.MOVE, x64.WindowsInputRegisters[0], 0) final.DLLCall("kernel32.ExitProcess") } @@ -74,15 +71,15 @@ func (r *Result) finalize() ([]byte, []byte, dll.List) { switch config.TargetOS { case "linux": - final.RegisterNumber(asm.MOVE, x64.SyscallInputRegisters[0], linux.Exit) + final.RegisterNumber(asm.MOVE, x64.SyscallInputRegisters[0], LinuxExit) final.RegisterNumber(asm.MOVE, x64.SyscallInputRegisters[1], 1) final.Syscall() case "mac": - final.RegisterNumber(asm.MOVE, x64.SyscallInputRegisters[0], mac.Exit) + final.RegisterNumber(asm.MOVE, x64.SyscallInputRegisters[0], MacExit) final.RegisterNumber(asm.MOVE, x64.SyscallInputRegisters[1], 1) final.Syscall() case "windows": - final.RegisterNumber(asm.MOVE, windows.X64InputRegisters[0], 1) + final.RegisterNumber(asm.MOVE, x64.WindowsInputRegisters[0], 1) final.DLLCall("kernel32.ExitProcess") } diff --git a/src/core/CompileCall.go b/src/core/CompileCall.go index fe63447..8b62b0a 100644 --- a/src/core/CompileCall.go +++ b/src/core/CompileCall.go @@ -7,7 +7,7 @@ import ( "git.akyoto.dev/cli/q/src/errors" "git.akyoto.dev/cli/q/src/expression" "git.akyoto.dev/cli/q/src/types" - "git.akyoto.dev/cli/q/src/windows" + "git.akyoto.dev/cli/q/src/x64" ) // CompileCall executes a function call. @@ -36,7 +36,7 @@ func (f *Function) CompileCall(root *expression.Expression) (*Function, error) { if pkg == "kernel32" || pkg == "user32" || pkg == "gdi32" || pkg == "comctl32" { parameters := root.Children[1:] - registers := windows.X64InputRegisters[:len(parameters)] + registers := x64.WindowsInputRegisters[:len(parameters)] for i := len(parameters) - 1; i >= 0; i-- { _, err := f.ExpressionToRegister(parameters[i], registers[i]) diff --git a/src/elf/ELF.go b/src/elf/ELF.go index af9b469..5ac1cb2 100644 --- a/src/elf/ELF.go +++ b/src/elf/ELF.go @@ -6,7 +6,7 @@ import ( "io" "git.akyoto.dev/cli/q/src/config" - "git.akyoto.dev/cli/q/src/exe" + "git.akyoto.dev/cli/q/src/fs" ) // ELF represents an ELF file. @@ -21,8 +21,8 @@ func Write(writer io.Writer, code []byte, data []byte) { const HeaderEnd = HeaderSize + ProgramHeaderSize*2 var ( - codeStart, codePadding = exe.Align(HeaderEnd, config.Align) - dataStart, dataPadding = exe.Align(codeStart+len(code), config.Align) + codeStart, codePadding = fs.Align(HeaderEnd, config.Align) + dataStart, dataPadding = fs.Align(codeStart+len(code), config.Align) ) elf := &ELF{ diff --git a/src/exe/Align.go b/src/fs/Align.go similarity index 95% rename from src/exe/Align.go rename to src/fs/Align.go index 024df62..1ae4f0b 100644 --- a/src/exe/Align.go +++ b/src/fs/Align.go @@ -1,4 +1,4 @@ -package exe +package fs // Align calculates the next aligned address and the padding needed. func Align[T int | uint | int64 | uint64 | int32 | uint32](n T, alignment T) (T, T) { diff --git a/src/macho/MachO.go b/src/macho/MachO.go index ef44ff1..5353a6d 100644 --- a/src/macho/MachO.go +++ b/src/macho/MachO.go @@ -6,7 +6,7 @@ import ( "io" "git.akyoto.dev/cli/q/src/config" - "git.akyoto.dev/cli/q/src/exe" + "git.akyoto.dev/cli/q/src/fs" ) // MachO is the executable format used on MacOS. @@ -26,8 +26,8 @@ func Write(writer io.Writer, code []byte, data []byte) { ) var ( - codeStart, codePadding = exe.Align(HeaderEnd, config.Align) - dataStart, dataPadding = exe.Align(codeStart+len(code), config.Align) + codeStart, codePadding = fs.Align(HeaderEnd, config.Align) + dataStart, dataPadding = fs.Align(codeStart+len(code), config.Align) ) m := &MachO{ diff --git a/src/pe/EXE.go b/src/pe/EXE.go index 6b2c5df..5ab108f 100644 --- a/src/pe/EXE.go +++ b/src/pe/EXE.go @@ -7,7 +7,7 @@ import ( "git.akyoto.dev/cli/q/src/config" "git.akyoto.dev/cli/q/src/dll" - "git.akyoto.dev/cli/q/src/exe" + "git.akyoto.dev/cli/q/src/fs" ) // EXE is the portable executable format used on Windows. @@ -26,9 +26,9 @@ func Write(writer io.Writer, code []byte, data []byte, dlls dll.List) { NumSections := 3 HeaderEnd := DOSHeaderSize + NTHeaderSize + OptionalHeader64Size + SectionHeaderSize*NumSections - codeStart, codePadding := exe.Align(HeaderEnd, config.Align) - dataStart, dataPadding := exe.Align(codeStart+len(code), config.Align) - importsStart, importsPadding := exe.Align(dataStart+len(data), config.Align) + codeStart, codePadding := fs.Align(HeaderEnd, config.Align) + dataStart, dataPadding := fs.Align(codeStart+len(code), config.Align) + importsStart, importsPadding := fs.Align(dataStart+len(data), config.Align) subSystem := IMAGE_SUBSYSTEM_WINDOWS_CUI @@ -91,7 +91,7 @@ func Write(writer io.Writer, code []byte, data []byte, dlls dll.List) { importSectionSize := len(imports)*8 + len(dllData) + importDirectorySize imageSize := importsStart + importSectionSize - imageSize, _ = exe.Align(imageSize, config.Align) + imageSize, _ = fs.Align(imageSize, config.Align) pe := &EXE{ DOSHeader: DOSHeader{ diff --git a/src/windows/Registers.go b/src/windows/Registers.go deleted file mode 100644 index 1043298..0000000 --- a/src/windows/Registers.go +++ /dev/null @@ -1,36 +0,0 @@ -package windows - -import ( - "git.akyoto.dev/cli/q/src/arm64" - "git.akyoto.dev/cli/q/src/cpu" - "git.akyoto.dev/cli/q/src/x64" -) - -var ( - X64InputRegisters = []cpu.Register{ - x64.RCX, - x64.RDX, - x64.R8, - x64.R9, - } - - X64OutputRegisters = []cpu.Register{ - x64.RAX, - } - - ARM64InputRegisters = []cpu.Register{ - arm64.X0, - arm64.X1, - arm64.X2, - arm64.X3, - arm64.X4, - arm64.X5, - arm64.X6, - arm64.X7, - } - - ARM64OutputRegisters = []cpu.Register{ - arm64.X0, - arm64.X1, - } -) diff --git a/src/x64/Registers.go b/src/x64/Registers.go index 9162141..0dc55b9 100644 --- a/src/x64/Registers.go +++ b/src/x64/Registers.go @@ -28,4 +28,6 @@ var ( GeneralRegisters = []cpu.Register{RCX, RBX, RBP, R11, R12, R13, R14, R15} InputRegisters = SyscallInputRegisters OutputRegisters = SyscallInputRegisters + WindowsInputRegisters = []cpu.Register{RCX, RDX, R8, R9} + WindowsOutputRegisters = []cpu.Register{RAX} )