0
votes

I have the following assembly code:

.data
.text

entry_point:
    pushq %rbp
    movq %rsp, %rbp
    popq %rbp
    ret

.global _main
_main:
    pushq %rbp
    movq %rsp, %rbp
    call entry_point
    popq %rbp
    ret

On my MacBook it compiles and runs fine, but I've just tried to make it run on Linux/Ubuntu 17.x and it gives me a segmentation fault. I ran it with GDB and it just tells me there is a SIGSEGV in ?? (), ... nothing really useful.

After checking with LLDB it tells me that:

... SIGSEGV: invalid address (fault address: 0x1)
memory read failed for 0x0

Still not really sure what this means however, and I don't know why it seg faults since the program, to me, is two functions with a stack frame setup and a simple call?

The entry point to my program is the _main procedure. libc is linked with my assembly program.

As per the suggestion, I re-wrote my assembly program to use a system exit call instead of "ret":

.data
.text
entry_point:
    pushq %rbp
    movq %rsp, %rbp
    popq %rbp
    ret

.global main
main:
    pushq %rbp
    movq %rsp, %rbp
    call entry_point
    popq %rbp
    movq $60, %rax
    movq $2, %rdi
    syscall

And I run this program as:

as foo.s -o foo.o
ld foo.o -lc
./a.out

But I get the following:

ld: warning: cannot find entry symbol _start; defaulting to 00000000004001d3
1
On linux you can't use ret to end your program. You need an exit syscall. It's not quite clear whether you are using libc or not, also which one is your actual entry point.Jester
@Jester I think this solves my problem, I did not know this... will update my question to clarify howeverflooblebit
On Linux it needs to be main. not _main if linking with the C startupMichael Petch
@MichaelPetch Interesting, why is that? Why does OS X not mind the underscore?flooblebit
Because OS/X uses MACHO and Linux uses ELF.Michael Petch

1 Answers

0
votes

ld foo.o -lc

That command does not build a valid executable. In particular, libc requires certain initialization (usually performed by crt0.o, which is added by the compiler driver), and that initialization is not happening here.

Generally, you should never link user-level programs directly with ld -- use the compiler driver, such as gcc instead:

gcc foo.s

will build your program correctly.