Bus error from x86_64 assembly anonymous function

120 Views Asked by At

I am writing a Lisp compiler that targets x86_64. My current goal is to implement the special form lambda. I recently discovered that you can take the address of a label, store it in a register, and call it from that:

lea rax, [f + rip]
call rax

Cool! That has a lot of potential. But I am getting an error in a test I did:

When I give my compiler this,

(define f (lambda (x) (+ x 1)))
(display_num (f 2))

it yields this.

    .global _main
    .text
_main:
    call _begin_gc
    and rsp, -16
    jmp after_lambda_1
    lambda_1:
    push rbp
    mov rbp, rsp
    push 1  # push argument to +
    push [rbp + 16]  # push argument to +
    call plus
    add rsp, 16  # discard 2 local arguments
    mov rbp, rsp
    pop rbp
    ret
    after_lambda_1:
    lea rax, [lambda_1 + rip]
    mov [f + rip], rax
    push 2  # push argument to f
    call f
    add rsp, 8  # discard 1 local argument
    push rax  # result of f
    call display_num
    add rsp, 8  # discard 1 local argument
    and rsp, -16
    call _end_gc
    xor rdi, rdi
    mov rax, 0x2000001
    syscall

    .data
f:
    .quad 0

That seemed okay at first. I got a bus error when running it though:

$ make run
./out/test
make: *** [run] Bus error: 10

Hm! weird. I ran it through LLDB next:

(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=2, address=0x100008050)
  * frame #0: 0x0000000100008050 test`f
    frame #1: 0x0000000100003d9c test`after_lambda_1 + 21
    frame #2: 0x0000000100003d67 test`main + 5
    frame #3: 0x00007fff72c13cc9 libdyld.dylib`start + 1
    frame #4: 0x00007fff72c13cc9 libdyld.dylib`start + 1

It says that it failed here,

test`f:
->  0x100008050 <+0>: jo     0x10000808f               ; gc + 55
    0x100008052 <+2>: add    byte ptr [rax], al
    0x100008054 <+4>: add    dword ptr [rax], eax
    0x100008056 <+6>: add    byte ptr [rax], al

but I don't see a line that looks like that in my code. I am utterly confused. Does anyone know what is happening here, why I am getting a bus error, and what I need to tweak to make my code functional? I am assembling on MacOS with Clang.

0

There are 0 best solutions below