From 0de27e01fdb9b7680ea65d7af1fce48d95d06740 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robin=20B=C3=A4rtschi?= Date: Fri, 14 Mar 2025 16:40:53 +0100 Subject: [PATCH] i am so fucking stupid, how tf did i manage to mess this up I used the rsp register instead of the rbp register for accessing the stack variables, rsp is the wrong base and changes constantly fuck --- asm/amd64/amd64.go | 20 ++++++++--------- asm/amd64/codegen.go | 52 ++++++++++++++++++++++++++------------------ flake.lock | 6 ++--- flake.nix | 3 ++- 4 files changed, 46 insertions(+), 35 deletions(-) diff --git a/asm/amd64/amd64.go b/asm/amd64/amd64.go index 1b492eb..4f830a0 100644 --- a/asm/amd64/amd64.go +++ b/asm/amd64/amd64.go @@ -5,13 +5,13 @@ import ( "strings" ) -var callConvArgs map[int]Register = map[int]Register{ - 1: DI, - 2: SI, - 3: DX, - 4: CX, - 5: R8, - 6: R9, +var callConvArgs []Register = []Register{ + DI, + SI, + DX, + CX, + R8, + R9, } type Program struct { @@ -68,7 +68,7 @@ type Function struct { func (f *Function) Emit() string { var builder strings.Builder - builder.WriteString(fmt.Sprintf("%s:\n push rbp\n mov rbp, rsp\n add rsp, %d\n", f.Name, f.StackOffset)) + builder.WriteString(fmt.Sprintf("%s:\n push rbp\n mov rbp, rsp\n", f.Name)) for _, inst := range f.Instructions { builder.WriteString(fmt.Sprintf(" %s\n", inst.InstructionString())) @@ -128,7 +128,7 @@ type SimpleInstruction struct { func (i *SimpleInstruction) InstructionString() string { if i.Opcode == Ret { - return fmt.Sprintf("mov rsp, rbp\n pop rbp\n ret\n") + return fmt.Sprintf("leave\n ret\n") } // No operands @@ -316,7 +316,7 @@ func (s Stack) OperandString(size OperandSize) string { sizeString = "qword" } - return fmt.Sprintf("%s [rsp %+d]", sizeString, s) + return fmt.Sprintf("%s [rbp %+d]", sizeString, s) } type Pseudo string diff --git a/asm/amd64/codegen.go b/asm/amd64/codegen.go index 7995657..d6422c7 100644 --- a/asm/amd64/codegen.go +++ b/asm/amd64/codegen.go @@ -134,7 +134,7 @@ func cgInstruction(i ttir.Instruction) []Instruction { case *ttir.Copy: return []Instruction{comment(i.String()), &SimpleInstruction{Opcode: Mov, Lhs: toAsmOperand(i.Dst), Rhs: toAsmOperand(i.Src)}} case *ttir.Call: - registerArgs := i.Arguments[0:min(len(callConvArgs), len(i.Arguments))] + registerArgs := i.Arguments[:min(len(callConvArgs), len(i.Arguments))] stackArgs := []ttir.Operand{} if len(callConvArgs) < len(i.Arguments) { stackArgs = i.Arguments[len(callConvArgs):len(i.Arguments)] @@ -273,7 +273,7 @@ type replacePseudoPass struct { } func replacePseudo(prog Program) Program { - newFunctions := make([]Function, 0) + newFunctions := []Function{} for _, f := range prog.Functions { newFunctions = append(newFunctions, rpFunction(f)) @@ -283,7 +283,7 @@ func replacePseudo(prog Program) Program { } func rpFunction(f Function) Function { - newInstructions := make([]Instruction, 0) + newInstructions := []Instruction{} r := &replacePseudoPass{ identToOffset: make(map[string]int64), @@ -337,7 +337,7 @@ func pseudoToStack(op Operand, r *replacePseudoPass) Operand { // Third pass, fixup invalid instructions func instructionFixup(prog Program) Program { - newFuncs := make([]Function, 0) + newFuncs := []Function{} for _, f := range prog.Functions { newFuncs = append(newFuncs, fixupFunction(f)) @@ -348,7 +348,17 @@ func instructionFixup(prog Program) Program { func fixupFunction(f Function) Function { // The function will at minimum require the same amount of instructions, but never less - newInstructions := make([]Instruction, 0) + newInstructions := []Instruction{} + + if f.StackOffset != 0 { + stack := -f.StackOffset + if stack > 0 { + stack = stack + (16 - (stack % 16)) + } else { + stack = stack - (16 - (stack % 16)) + } + newInstructions = append(newInstructions, comment(fmt.Sprintf("Allocated %d on stack", stack)), AllocateStack(stack)) + } for _, i := range f.Instructions { newInstructions = append(newInstructions, fixupInstruction(i)...) @@ -363,13 +373,13 @@ func fixupInstruction(i Instruction) []Instruction { case *SimpleInstruction: switch i.Opcode { case Mov: - if lhs, ok := i.Lhs.(Stack); ok { - if rhs, ok := i.Rhs.(Stack); ok { + if dst, ok := i.Lhs.(Stack); ok { + if src, ok := i.Rhs.(Stack); ok { return []Instruction{ comment("FIXUP: Stack and Stack for Mov"), comment(i.InstructionString()), - &SimpleInstruction{Opcode: Mov, Lhs: Register(R10), Rhs: rhs}, - &SimpleInstruction{Opcode: Mov, Lhs: lhs, Rhs: Register(R10)}, + &SimpleInstruction{Opcode: Mov, Lhs: R10, Rhs: src}, + &SimpleInstruction{Opcode: Mov, Lhs: dst, Rhs: R10}, } } } @@ -378,9 +388,9 @@ func fixupInstruction(i Instruction) []Instruction { return []Instruction{ comment("FIXUP: Stack as Dst for Imul"), comment(i.InstructionString()), - &SimpleInstruction{Opcode: Mov, Lhs: Register(R11), Rhs: lhs}, - &SimpleInstruction{Opcode: Imul, Lhs: Register(R11), Rhs: i.Rhs}, - &SimpleInstruction{Opcode: Mov, Lhs: lhs, Rhs: Register(R11)}, + &SimpleInstruction{Opcode: Mov, Lhs: R11, Rhs: lhs}, + &SimpleInstruction{Opcode: Imul, Lhs: R11, Rhs: i.Rhs}, + &SimpleInstruction{Opcode: Mov, Lhs: lhs, Rhs: R11}, } } fallthrough @@ -390,16 +400,16 @@ func fixupInstruction(i Instruction) []Instruction { return []Instruction{ comment("FIXUP: Stack and Stack for Binary"), comment(i.InstructionString()), - &SimpleInstruction{Opcode: Mov, Lhs: Register(R10), Rhs: rhs}, - &SimpleInstruction{Opcode: i.Opcode, Lhs: lhs, Rhs: Register(R10)}, + &SimpleInstruction{Opcode: Mov, Lhs: R10, Rhs: rhs}, + &SimpleInstruction{Opcode: i.Opcode, Lhs: lhs, Rhs: R10}, } } } else if lhs, ok := i.Lhs.(Imm); ok && i.Opcode == Idiv { return []Instruction{ comment("FIXUP: Imm as Dst for Idiv"), comment(i.InstructionString()), - &SimpleInstruction{Opcode: Mov, Lhs: Register(R10), Rhs: lhs}, - &SimpleInstruction{Opcode: Idiv, Lhs: Register(R10)}, + &SimpleInstruction{Opcode: Mov, Lhs: R10, Rhs: lhs}, + &SimpleInstruction{Opcode: Idiv, Lhs: R10}, } } case Cmp: @@ -408,8 +418,8 @@ func fixupInstruction(i Instruction) []Instruction { return []Instruction{ comment("FIXUP: Stack and Stack for Cmp"), comment(i.InstructionString()), - &SimpleInstruction{Opcode: Mov, Lhs: Register(R10), Rhs: rhs}, - &SimpleInstruction{Opcode: i.Opcode, Lhs: lhs, Rhs: Register(R10)}, + &SimpleInstruction{Opcode: Mov, Lhs: R10, Rhs: rhs}, + &SimpleInstruction{Opcode: i.Opcode, Lhs: lhs, Rhs: R10}, } } } else if lhs, ok := i.Lhs.(Imm); ok { @@ -418,12 +428,12 @@ func fixupInstruction(i Instruction) []Instruction { comment(i.InstructionString()), &SimpleInstruction{ Opcode: Mov, - Lhs: Register(R11), - Rhs: Imm(lhs), + Lhs: R11, + Rhs: lhs, }, &SimpleInstruction{ Opcode: Cmp, - Lhs: Register(R11), + Lhs: R11, Rhs: i.Rhs, }, } diff --git a/flake.lock b/flake.lock index 9191c49..ddcdfd6 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1739214665, - "narHash": "sha256-26L8VAu3/1YRxS8MHgBOyOM8xALdo6N0I04PgorE7UM=", + "lastModified": 1741851582, + "narHash": "sha256-cPfs8qMccim2RBgtKGF+x9IBCduRvd/N5F4nYpU0TVE=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "64e75cd44acf21c7933d61d7721e812eac1b5a0a", + "rev": "6607cf789e541e7873d40d3a8f7815ea92204f32", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index c0d1846..e65f409 100644 --- a/flake.nix +++ b/flake.nix @@ -45,8 +45,9 @@ ( if system == "x86_64-linux" then [fasm gdb] - else [lldb] + else [] ) + lldb ]; }; });