I am using Linux 2.6.31-14 on Intel 32-bit processor.
C file:
#include <stdio.h>
main()
{
printf("Hello World!\n");
}
Linker script:
SECTIONS{
.text 0x00000100 :{
*(.text)
}
}
Output:
$ gcc -S test.c
$ as -o test.o test.s
$ ld -T linker.ld -dynamic-linker /lib/ld-linux.so.2 -o test test.o
test.o: In function `main':
test.c:(.text+0x11): undefined reference to `puts'
What is wrong? How can I make the linker script use the dynamic C library?
I think that you should link your program with C standard library (libc.so) by adding -lc option to ld arguments.
ld -T linker.ld -lc -dynamic-linker /lib/ld-linux.so.2 -o test test.o
Also you may have some problems with running your program (segmentation faults) because your test.o have no program entry point (_start symbol). So you will need additional object file with entry point that is calling your main() function inside test.o and than termitates code execution by calling exit() system call.
Here is start.s code
# Linux system calls constants
.equ SYSCALL_EXIT, 1
.equ INTERRUPT_LINUX_SYSCALL, 0x80
# Code section
.section .text
.globl _start
_start: # Program entry point
call main # Calling main function
# Now calling exit() system call
movl %eax, %ebx # Saving return value for exit() argument
movl $SYSCALL_EXIT, %eax # System call number
int $INTERRUPT_LINUX_SYSCALL # Raising programm interrupt
Then you should build your program
gcc test.c -S
as test.s -o test.o
as start.s -o start.o
ld start.o test.o -o test -lc --dynamic-linker=/lib/ld-linux.so.2
You may also want to check out this article https://blogs.oracle.com/ksplice/entry/hello_from_a_libc_free to learn more about how C compiler and standard library works.
You are not linking in the c library.
On my 64bit system it's:
-dynamic-linker /lib64/ld-linux-x86-64.so.2 /lib64/libc.so.6
Related
How to use nasm to create gui under linux
I found an example ,https://gist.github.com/nikAizuddin/6fbbc703f1213ab61a8a
but i get an error
nasm main.asm -o main.o -felf64 -w+all -gstabs
ld main.o -o a -melf_x86_64 -dynamic-linker /lib/ld-linux.so.2 -lX11
print zsh: accessing a corrupt shared library: ./a
what happened?
I am trying to compile test.c as described this NanoPi Neo guide. However, when ever I try to run the gcc command to compile, I get this error message...
GNU ld (GNU Binutils for Ubuntu) 2.26.1
Supported emulations:
armelf_linux_eabi
armelfb_linux_eabi
/usr/lib/gcc/arm-linux-gnueabihf/5/../../../arm-linux-gnueabihf/crt1.o: In function `_start':
(.text+0x28): undefined reference to `main'
collect2: error: ld returned 1 exit status
...the command...
sudo gcc -Wall -o test.c -lwiringPi -lpthread -Wl,-V
...and the code I'm trying to compile...
#include <wiringPi.h>
int main(void)
{
wiringPiSetup() ;
pinMode (7, OUTPUT) ;
for(;;)
{
digitalWrite(7, HIGH) ;
delay (500) ;
digitalWrite(7, LOW) ;
delay (500) ;
}
}
May I guess that this is a possible linking issue? I'm just not sure and I really do know how to change it.
I am rather novice-like when it comes to topics like C, Linux and the like. :)
You have not specified any .c source files since the -o specifies the output as #user3386109 mentioned.
sudo gcc -Wall test.c -o output_file_name -lwiringPi -lpthread -Wl,-V
This question already has answers here:
"relocation R_X86_64_32S against `.bss' can not be used when making a shared object”
(2 answers)
32-bit absolute addresses no longer allowed in x86-64 Linux?
(1 answer)
Closed 3 years ago.
I'm trying to call a C function from assembly. However my assembly code uses a .bss section which is causing me some troubles linking the file.
Here is the error I am getting
/usr/bin/ld: server.o: relocation R_X86_64_32S against `.bss' can not be used when making a PIE object; recompile with -fPIC
/usr/bin/ld: final link failed: Nonrepresentable section on output
collect2: error: ld returned 1 exit status
Makefile:8: recipe for target 'all' failed
make: *** [all] Error 1
I've created a minimal example of the issue I am having just to show the problem as clear as I can.
server.s
global main
extern send_to_queue
bits 64
section .bss
sockfd: resq 1
section .text
main:
push 99
push 1
mov rdi, 1
mov rsi, 2
call send_to_queue
add rsp, 16
; return 0;
mov rax, 0
mov byte[sockfd], 10
mov r10, [sockfd]
ret
func.c
#include <stdio.h>
void send_to_queue(int log, int length) {
printf("%d, %d", log, length);
}
makefile
OBJECTS = func.o server.o
CC = gcc
CFLAGS = -std=c11 -m64 -Wall -Wextra -Werror -c
AS = nasm
ASFLAGS = -elf64
all: $(OBJECTS)
gcc -m64 $(OBJECTS) -o server
run: all
./server
%.o: %.c
$(CC) $(CFLAGS) $< -o $#
%.o: %.s
$(AS) $(ASFLAGS) $< -o $#
clean:
rm -rf $(OBJECTS) server
I have tried to use the flag -fPIC as the error message suggest however it is not working for me.I have also tried to use -static flag in the cflags but that also did not help. If anyone has some insight on this issue it would be appreciated. Thanks.
I link a shared library on the command line while building an executable. Running ldd on that executable is not showing the linked shared library.
After looking at some of the output of the linker, I have even tried adding the -Wl,--no-as-needed option and that didn't help either.
foo.c:
#include <stdio.h>
void foo () {
printf ("Hello world\n");
}
main.c:
#include <stdio.h>
int main () {
printf ("In main \n");
foo ();
}
Here's the command I used to compile and link:
$ gcc -Wl,--no-as-needed main.c -o main -L./ -lfoo
/bin/ld: cannot find -lfoo
collect2: error: ld returned 1 exit status
$ gcc -c foo.c -shared -Wl,-soname,libfoo.so -o libfoo.so
$ ls -l libfoo.so
-rw-r--r-- 1 apple eng 1488 Jun 4 04:44 libfoo.so
$ gcc -Wl,--no-as-needed main.c -o main -L./ -lfoo
$ ldd main
linux-vdso.so.1 => (0x00007fffbdd6c000)
libc.so.6 => /lib64/libc.so.6 (0x00007f6367e23000)
/lib64/ld-linux-x86-64.so.2 (0x00005556e268a000)
libfoo.so does not show up above.
$ objdump -x main | grep NEEDED
NEEDED libc.so.6
Why isn't libfoo.so showing up as NEEDED?
By using the gcc option -c you're telling it to create only object from foo.c, so the only product you're getting from this gcc command is an object file. The fact that its suffix is .so is only because you forced it using -o option. If you run this command without -o you'd see that the output is just foo.o - an object file.
If you omit the -c from the gcc command you'd get the shared object you wanted.
Running file on the output file shows the difference (note that I'm not setting the output name using -o and letting gcc use its default names):
With -c:
> gcc -c foo.c -shared
> file foo.o
foo.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
Without -c:
> gcc foo.c -shared
> file a.out
a.out: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=a63581bfc45f845c501ffb6635, not stripped
^^^
|||
This command does not generate a shared library:
gcc -c foo.c -shared -Wl,-soname,libfoo.so -o libfoo.so
It generates an object file libfoo.so that is later statically linked with your code. Proof: remove the lib file, the program will still run.
Solution:
Compile the object file separately, then convert it into a shared library. You will have to tell the loader where to search for the shared libraries by setting LD_LIBRARY_PATH:
gcc -c foo.c
gcc foo.o -shared -o libfoo.so
gcc main.c -o main -L./ -lfoo
export LD_LIBRARY_PATH=`pwd`
ldd ./main
# linux-vdso.so.1 (0x00007ffe0f7cb000)
# libfoo.so => /home/---/tmp/libfoo.so (0x00007f9bab6ec000)
# libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f9bab2fb000)
# /lib64/ld-linux-x86-64.so.2 (0x00007f9babaf0000)
My File name is hello.c
#include<stdio.h>
int main(void)
{
printf("Hello World!");
return 0;
}
and the commands I gave are:
$ gcc hello.c -o hello
$ gcc ./hello
The Terminal output is:
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
Can please Anyone help me?
I use:
gcc version 7.2.0 (Debian 7.2.0-20)
$ gcc hello.c -o hello
$ gcc ./hello
Assuming you were trying to run it with that second command, it should just be ./hello (in other words, get rid of the gcc at the start).
What you're trying to do is compile/link the executable file that you've already compiled from source, when it's already in a state where it can be run.