Search code examples
macosassemblyreturnstackx86-64

Why is my x86 linked-list function throwing a segfault?


I have been writing code high and low, all day long to try to get a linked list in x86 assembly. Nothing works, and it is so very frustrating. I am trying to make one that has elements 1, 2, and 3. GDB told me that it was segfaulting in the ret statement at end, but didn't provide any more info. Can anyone help me with this? I am assembling on a Mac with Clang.

Here is my code:

    .global _main
    .text

/*
r12: result
r14: number of elements left in list
r15: stack offset for accessing arguments
*/

make_list:
    # # # # #
    push rbp
    mov rbp, rsp
    # # # # #
    mov rdi, [rbp + r15]
    mov qword ptr [rax], rdi  # assign first_node.head
    lea r13, [rax + 8]  # store address of first_node.tail
    # # # # #
    mov rdi, 16
    sub rsp, 8
    call _malloc
    add rsp, 8
    # # # # #
    add r15, 8
    sub r14, 1
    # # # # #
    mov rdi, [rbp + r15]
    mov qword ptr [r13], rdi  # assign second_node.head
    # # # # #
    cmp r14, 0
    je end
    # # # # #
    mov rdi, 16
    sub rsp, 8
    call _malloc
    add rsp, 8
    # # # # #
    jmp make_list  # assign second_node.tail to an argument
    # # # # #
    end:
        mov qword ptr [r13 + 8], 0  # second_node.tail = NULL
        mov rsp, rbp
        pop rbp
        ret
    # # # # #

_main:
    # # # # #
    mov rdi, 16
    sub rsp, 8
    call _malloc
    add rsp, 8
    lea r12, [rax]
    # # # # #
    mov r14, 3
    mov r15, 16
    # # # # #
    push 3
    push 2
    push 1
    # # # # #
    call make_list
    add rsp, 24
    # # # # #
    mov rdi, 0
    mov rax, 0x2000001
    syscall
    # # # # #

Solution

  • The jmp make_list instruction is incorrect. You don't want to jump to the start of the function, where you much rbp again, but to somewhere partway in to your function, after all of your setup.

    The multiple push rbp instructions that don't get popped before the ret cause the instruction pointer to get an invalid value in it, resulting in your setfault.