Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

linking llvm produced object code with ld

Tags:

gcc

llvm

ld

I have written a small compiler that uses llvm (through c++) to produce object files (in a linux system).

When I link the compiled output with gcc, the program runs fine:

myCompiler source.mylang -o objCode
gcc objCode -o program
./program #runs fine

But if I try to link it with ld, I get a segmentation fault when I run the program:

myCompiler source.mylang -o objCode
ld objCode -e main -o program   #ld does not print any error or warning.
./program #Segmentation fault (core dumped)

Here is the llvm code that the compiler outputs (using myLlvmModule->print function):

; ModuleID = 'entryPointModule'
source_filename = "entryPointModule"

define i32 @main() {
entry:
  %x = alloca i32
  store i32 55, i32* %x
  ret i32 0
  ret i32 0
}

Why ld fails, when gcc succeeds? I thought that after writting a compiler, the only needed step would be to call a linker. Is an other compiler (such as gcc) necessary?

If yes, why? If no, how can I have ld working?

EDIT: readelf -d of the working binary:

Dynamic section at offset 0xe00 contains 24 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000000c (INIT)               0x4b8
 0x000000000000000d (FINI)               0x684
 0x0000000000000019 (INIT_ARRAY)         0x200df0
 0x000000000000001b (INIT_ARRAYSZ)       8 (bytes)
 0x000000000000001a (FINI_ARRAY)         0x200df8
 0x000000000000001c (FINI_ARRAYSZ)       8 (bytes)
 0x000000006ffffef5 (GNU_HASH)           0x298
 0x0000000000000005 (STRTAB)             0x348
 0x0000000000000006 (SYMTAB)             0x2b8
 0x000000000000000a (STRSZ)              125 (bytes)
 0x000000000000000b (SYMENT)             24 (bytes)
 0x0000000000000015 (DEBUG)              0x0
 0x0000000000000003 (PLTGOT)             0x200fc0
 0x0000000000000007 (RELA)               0x3f8
 0x0000000000000008 (RELASZ)             192 (bytes)
 0x0000000000000009 (RELAENT)            24 (bytes)
 0x000000000000001e (FLAGS)              BIND_NOW
 0x000000006ffffffb (FLAGS_1)            Flags: NOW PIE
 0x000000006ffffffe (VERNEED)            0x3d8
 0x000000006fffffff (VERNEEDNUM)         1
 0x000000006ffffff0 (VERSYM)             0x3c6
 0x000000006ffffff9 (RELACOUNT)          3
 0x0000000000000000 (NULL)               0x0

the same command for the corrupt binary:

There is no dynamic section in this file.
like image 788
Alkis Mavridis Avatar asked Jun 29 '26 18:06

Alkis Mavridis


1 Answers

Your entry point attempts to return to a return address on the stack which does not exist, which is why the program jumps to address zero.

The entry point of a program is not expected to return. It must terminate the process by calling _exit (or a related system call).

like image 153
Florian Weimer Avatar answered Jul 02 '26 11:07

Florian Weimer



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!