flat assembler
Message board for the users of flat assembler.

Index > Linux > simple sdl game segfaults on 64bit linux, why?

Author
Thread Post new topic Reply to topic
ginere



Joined: 15 Oct 2017
Posts: 13
ginere 23 Oct 2017, 14:36
Code:
format ELF64
public main
extrn SDL_Init

section '.text' executable
main:
    mov edi,$30
    call SDL_Init
    ret

section '.data' writeable
    


Code:
fasm main.asm
gcc main.o `sdl2-config --libs --cflags` -o main
    


Starting ./main gives me "Segmentation fault". Why?
Post 23 Oct 2017, 14:36
View user's profile Send private message Reply with quote
Furs



Joined: 04 Mar 2016
Posts: 2622
Furs 23 Oct 2017, 15:08
I don't think you can use 'ret' on Linux to exit from the entry point main, never seen it that way. Call exit instead:
Code:
mov eax, 60
syscall    
Also you might have to align the stack to 16 bytes before calling SDL_Init.
Post 23 Oct 2017, 15:08
View user's profile Send private message Reply with quote
ginere



Joined: 15 Oct 2017
Posts: 13
ginere 23 Oct 2017, 16:39
Furs wrote:
Also you might have to align the stack to 16 bytes before calling SDL_Init.


Thank you. That did the trick. Stack was aligned to $08 so I did sub rsp, $08 before SDL_Init, and after SDL_Init I put add rsp, $08 to get old rsp back.
Post 23 Oct 2017, 16:39
View user's profile Send private message Reply with quote
Furs



Joined: 04 Mar 2016
Posts: 2622
Furs 23 Oct 2017, 20:17
You should use a dummy push instead (e.g. push rax), it's much smaller (1 byte vs 4) and it's entry point anyway. Wink

I know that Linux is probably going to always give this (mis)alignment on entry point just to be compatible, but I'm just saying that libc (the library that hijacks the entry point of all C apps that use it on Linux) realigns the stack on entry point (as if it's unreliable). Paranoia? Razz But I'd err on the side of caution and just use a "and rsp, -16".
Post 23 Oct 2017, 20:17
View user's profile Send private message Reply with quote
system error



Joined: 01 Sep 2013
Posts: 670
system error 28 Nov 2017, 15:13
Furs wrote:
I don't think you can use 'ret' on Linux to exit from the entry point main, never seen it that way. Call exit instead:


"ret" IS the standard exit point for every main function of gcc binaries both on Windows and Linux. You been sending "patches" to GCC people and you didn't know this?? :O
Post 28 Nov 2017, 15:13
View user's profile Send private message Reply with quote
Furs



Joined: 04 Mar 2016
Posts: 2622
Furs 28 Nov 2017, 16:30
main function is not the entry point in C programs, ret works because the C runtime (which hijacks the entry point) calls it, so it then calls exit itself.

Of course I did say "entry point main" even in your quote but it's not like you can understand English.
Post 28 Nov 2017, 16:30
View user's profile Send private message Reply with quote
system error



Joined: 01 Sep 2013
Posts: 670
system error 28 Nov 2017, 17:58
Quote:
main function is not the entry point in C programs
That says a lot about your "expertise" xD

Quote:
ret works because the C runtime (which hijacks the entry point) calls it, so it then calls exit itself.


"ret" will always work because the return address is in RSP. Doesn't need extra "hijacking" and all those "expert" bullshits xD

Simple hello world's binaries;
Code:
#include <stdio.h>

int main()      //Try "int Expert_Begin()" here xD
{

        printf("Furs keeps sending patches to GCC...");
        return 0;
}    


output from GDB
Code:
    0x00000000004015b0 <+0>:     push   rbp
   0x00000000004015b1 <+1>:     mov    rbp,rsp
   0x00000000004015b4 <+4>:     sub    rsp,0x20
   0x00000000004015b8 <+8>:     call   0x401750 <__main>
   0x00000000004015bd <+13>:    lea    rcx,[rip+0x2a6c]        # 0x404030
   0x00000000004015c4 <+20>:    call   0x402b60 <printf>
   0x00000000004015c9 <+25>:    mov    eax,0x0
   0x00000000004015ce <+30>:    add    rsp,0x20
   0x00000000004015d2 <+34>:    pop    rbp
   0x00000000004015d3 <+35>:    ret    
Post 28 Nov 2017, 17:58
View user's profile Send private message Reply with quote
system error



Joined: 01 Sep 2013
Posts: 670
system error 28 Nov 2017, 18:20
Expert advise from Furs
Quote:
I don't think you can use 'ret' on Linux to exit from the entry point main, never seen it that way


Oopppsss (From C's main())
Code:
   0x00000000004015b0 <+0>:     push   rbp 
   0x00000000004015b1 <+1>:     mov    rbp,rsp 
   0x00000000004015b4 <+4>:     sub    rsp,0x20 
   0x00000000004015b8 <+8>:     call   0x401750 <__main> 
   0x00000000004015bd <+13>:    lea    rcx,[rip+0x2a6c]        # 0x404030 
   0x00000000004015c4 <+20>:    call   0x402b60 <printf> 
   0x00000000004015c9 <+25>:    mov    eax,0x0 
   0x00000000004015ce <+30>:    add    rsp,0x20 
   0x00000000004015d2 <+34>:    pop    rbp 
   0x00000000004015d3 <+35>:    ret ;==> gcc does it ALL THE TIME but Furs never "seen" it that way?? Baloney expert :O    
Post 28 Nov 2017, 18:20
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20622
Location: In your JS exploiting you and your system
revolution 28 Nov 2017, 22:52
So what is the answer? Can we, or can we not, simply use ret to return to the loader in Linux? Is it "official" or just a coincidence? Do the docs say anything on the matter? Do the docs even exist?
Post 28 Nov 2017, 22:52
View user's profile Send private message Visit poster's website Reply with quote
evk1



Joined: 18 Jun 2014
Posts: 24
evk1 29 Nov 2017, 00:33
revolution wrote:
So what is the answer? Can we, or can we not, simply use ret to return to the loader in Linux? Is it "official" or just a coincidence? Do the docs say anything on the matter? Do the docs even exist?

You can use ret, if you are going to link your object file with gcc (or another compiler). In this case gcc automatically includes precompiled startup code which calls the main function to you program.
However if you specify entry point manually (--entry=main with gcc, or entry main with fasm) you should not use ret, since at the time when program starts [rsp] contains not a return address, but argc.
The program startup process is documented in the ELF specification for x86_64.

_________________
Sorry for my English
Post 29 Nov 2017, 00:33
View user's profile Send private message Reply with quote
Melissa



Joined: 12 Apr 2012
Posts: 125
Melissa 29 Nov 2017, 06:04
revolution wrote:
So what is the answer? Can we, or can we not, simply use ret to return to the loader in Linux? Is it "official" or just a coincidence? Do the docs say anything on the matter? Do the docs even exist?


You use ret if your code is called from C runtime. If it is not you specify entry point,
usually _start and call sysexit.
If making standalone fasm executable sysexit is arbitrary and entry point wahtever.
You should be aware that in case of main called from C runtime rdi contains argc,rsi points to argv array. In case not, those values are on stack.
Post 29 Nov 2017, 06:04
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20622
Location: In your JS exploiting you and your system
revolution 29 Nov 2017, 10:54
Thanks for the answers everyone. I think system error owes Furs an apology.
Post 29 Nov 2017, 10:54
View user's profile Send private message Visit poster's website Reply with quote
system error



Joined: 01 Sep 2013
Posts: 670
system error 29 Nov 2017, 11:30
Edit by revolution: removed trolling


Last edited by system error on 30 Nov 2017, 06:05; edited 2 times in total
Post 29 Nov 2017, 11:30
View user's profile Send private message Reply with quote
Furs



Joined: 04 Mar 2016
Posts: 2622
Furs 29 Nov 2017, 13:04
@system error: In respect to the output from gdb, that's not his code, it's the C runtime's code which calls his main, so thanks for proving my point?

Usually, when people code "main" function in asm, I don't assume them to use the C runtime (why wouldn't they use C otherwise?). Don't get me wrong, I understand people who want total control over the code in their app (obviously excluding external library calls), but linking the C runtime automatically makes your program not contain only your own code, since it pulls it, so I don't see much point in coding "main" in asm then (the app will be semi-bloated anyway; I mean if you want main in asm, minimal bloat should be a goal no? not like main is a hot path).

(btw I don't use the C runtime even in C/C++ code, just pass -nostdlib to GCC Razz you can still use some of the standard library as normal imported dynamic libs, just not baked into your own app; some do require an "init" function call __init_libc_main tho)
Post 29 Nov 2017, 13:04
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.