Other Problem linking with libc

Hi I'm having a problem assembling a simple code calling a printf.
I'm linking it to libc but I get this undefined reference error.
does anyone know how to link to libc.

as asm-1.s -o asm-1.o
ld asm-1.o -o asm-1 --dynamic-linker /usr/libexec/ld-elf.so.1 -lc


Code:
/lib/libc.so.7: undefined reference to `__progname'
/lib/libc.so.7: undefined reference to `environ'
 
In FreeBSD all names in the libraries have an underscore prefixing every name. I.e. environ would be _environ in an assembly language program. This is actually a compiler convention.

Run gcc -S asm-1.c which will produce the file asm-1.s which is the assembly program. See gcc(1) for further details.

If you aren't able to compile it. Please, post your program code.
 
Thanks for advice but I'm not compiling C code its x86 assembly very basic code.
I found out a lot about how linker is invoked by this command

clang -v -m32 asm-1.s

I need to use this command
ld -dynamic-linker /libexec/ld-elf.so.1 -o asm-1 -lc asm-1.o /usr/lib32/crt1.o /usr/lib32/crti.o -m elf_i386_fbsd -e_start

But output is this because it requires C standard of having function main
Code:
/usr/lib32/crt1.o: In function `_start':
(.text+0x0): multiple definition of `_start'
asm-1.o:(.text+0x0): first defined here
/usr/lib32/crt1.o: In function `_start1':
/usr/src/lib/csu/i386-elf/crt1_c.c:(.text+0x156): undefined reference to `main'
Without crt1.o i get undefined references to __progname and environ. I want to know if there is some way around this.
 
Last edited by a moderator:
If you use clang to link, you get the C runtime by default, and your entry point should be main.
Code:
% cc -S hello.c
% cc -v -m64 hello.s
FreeBSD clang version 3.4.1 (tags/RELEASE_34/dot1-final 208032) 20140512
Target: x86_64-unknown-freebsd10.1
Thread model: posix
Selected GCC installation:
 "/usr/bin/cc" -cc1as -triple x86_64-unknown-freebsd10.1 -filetype obj -main-file-name hello.s -target-cpu x86-64 -fdebug-compilation-dir /root -dwarf-debug-producer FreeBSD clang version 3.4.1 (tags/RELEASE_34/dot1-final 208032) 20140512 -o /tmp/hello-5605f8.o hello.s
 "/usr/bin/ld" --eh-frame-hdr -dynamic-linker /libexec/ld-elf.so.1 --hash-style=both --enable-new-dtags -o a.out /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtbegin.o -L/usr/lib /tmp/hello-5605f8.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/crtend.o /usr/lib/crtn.o
% ./a.out
Hello, World!
 
I'm not using clang, just as() and ld() and can't link it dynamically to libc. One must have main function defined then must use C runtime and so on ... is there other way for dynamically linking to libc?

On Linux this is done this way
as somefile.s -o somefile.o
ld -dynamic-linker /lib/ld-linux.so.2 -o somefile -lc somefile.o
 
Last edited by a moderator:
I'm not using clang, just as() and ld() and can't link it dynamically to libc. One must have main function defined
then must use C runtime and so on ... is there other way for dynamically linking to libc?

on linux this is done this way
as somefile.s -o somefile.o
ld -dynamic-linker /lib/ld-linux.so.2 -o somefile -lc somefile.o

Run the following command to link:
ld -dynamic-linker /libexec/ld-elf.so.1 -o asm-1 -lc -lgcc asm-1.o /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtbegin.o -L /usr/lib /usr/lib/crtend.o /usr/lib/crtn.o
 
Code:
.section .text
.globl _start
_start:
   nop
   movl $0, %edi
loop:
   movl val(, %edi, 4), %eax
   pushl %eax
   pushl $out_str
   call printf
   addl $8, %esp
   inc %edi
   cmpl $11, %edi
   jne loop
   pushl $0
   call exit
   
.section .data
out_str:
   .asciz "The value is %d\n"
val:
   .int 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60

this is the code. the ld() command you told me works you just need to rename _start to main.
 
If you want to use a different entry point name than symbol _start, you can specify `-e' entry command-line option like:
ld -e _main -o out a.o
 
If you define environ and __progname:
Code:
.section .text
.globl _start
_start:
   nop
   movl $0, %edi
loop:
   movl val(, %edi, 4), %eax
   pushl %eax
   pushl $out_str
   call printf
   addl $8, %esp
   inc %edi
   cmpl $11, %edi
   jne loop
   pushl $0
   call exit

.section .data
out_str:
   .asciz "The value is %d\n"
val:
   .int 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60
.globl environ
.align 8
environ:
   .quad 0
   .size environ, 8
.globl __progname
__progname:
    .asciz "asm-1"
Then you can link with ld -dynamic-linker /libexec/ld-elf.so.1 -L /usr/lib32 -m elf_i386_fbsd -o asm-1 -lc asm-1.o and the program runs successfully.

But I don't know what the implications are of using libc without linking in crt*.o...
 
But I don't know what the implications are of using libc without linking in crt*.o...

I don't know what the implications are on FreeBSD but on Linux I used to dynamically link to libc without crt*.* and I tried the same way but it seems not possible without crt*.* or hack you proposed there is some implementation difference I guess

On Linux this is done this way
as somefile.s -o somefile.o
ld -dynamic-linker /lib/ld-linux.so.2 -o somefile -lc somefile.o

If you want to use a different entry point name than symbol _start, you can specify `-e' entry command-line option like:
If you're linking to libc you need to have main function even if you specify another entry point linking will fail.

ld -dynamic-linker /libexec/ld-elf.so.1 -e _main -lc asm-tst2.o -o asm-tst2 /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtn.o
Code:
/usr/lib/crt1.o: In function `_start':
/usr/src/lib/csu/amd64/crt1.c:(.text+0x16b): undefined reference to `main'
 
If you're linking to libc you need to have main function even if you specify another entry point linking will fail.

ld -dynamic-linker /libexec/ld-elf.so.1 -e _main -lc asm-tst2.o -o asm-tst2 /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtn.o
Code:
/usr/lib/crt1.o: In function `_start':
/usr/src/lib/csu/amd64/crt1.c:(.text+0x16b): undefined reference to `main'

C expects to run that startup code which contains the symbol _start and calls main. Try using `-nostartfiles -e _main' in this case.

But it may be easier to let gcc(1) invoke the linker.
 
The issue is really that crt1.o contains an unresolved symbol main and the linker will bomb on that if there's nothing to bind it to. You'll have to roll your own crt1.o if you want to avoid that.
 
The issue is really that crt1.o contains an unresolved symbol main and the linker will bomb on that if there's nothing to bind it to. You'll have to roll your own crt1.o if you want to avoid that.

Yup I know thats what I said If using libc you need main and -nostartfiles won't work

Code:
ld -dynamic-linker /libexec/ld-elf.so.1 -nostartfiles -e _main -lc asm-tst2-32.o -o asm-tst2-32 -m elf_i386_fbsd /usr/lib32/crt1.o /usr/lib32/crti.o /usr/lib32/crtn.o /usr/lib32/crtbegin.o /usr/lib32/crtend.o
/usr/lib32/crt1.o: In function `_start1':
/usr/src/lib/csu/i386-elf/crt1_c.c:(.text+0x8b): undefined reference to `atexit'
/usr/src/lib/csu/i386-elf/crt1_c.c:(.text+0x92): undefined reference to `_init_tls'
/usr/src/lib/csu/i386-elf/crt1_c.c:(.text+0xab): undefined reference to `atexit'
/usr/src/lib/csu/i386-elf/crt1_c.c:(.text+0x156): undefined reference to `main'
/usr/src/lib/csu/i386-elf/crt1_c.c:(.text+0x15e): undefined reference to `exit'
asm-tst2-32.o: In function `loop':
(.text+0x2a): undefined reference to `printf'
 
Back
Top