使用链接器构建程序但运行可执行文件显示“没有这样的文件或目录”

时间:2015-09-28 13:15:54

标签: c gcc linker ld toolchain

我编写了一个包含两个文件main.ccomp.c

的程序

的main.c

#include <stdio.h>
extern int secure_func(int, int);
void main()
{
    printf("hello, world\n");
    int result = secure_func(1, 1);
}

comp.c

int secure_func(int text, int key)
{
    return text * key * key;
}

首先,我直接使用gcc构建程序并运行可执行文件,这很好。

gcc -o main main.c comp.c
./main
hello, world

然后我尝试使用工具链逐步构建程序

gcc -c -o comp.o comp.c
gcc -c -o main.o main.c
ld -o main main.o comp.o -lc --entry main

ld生成文件main。但是,如果我尝试运行它,它会显示错误

bash: ./main: No such file or directory

可执行文件具有X权限。

列表信息

>    ~/test/segtest2$ ls -l
>    total 24
>    -rw-rw-r-- 1 kail kail   88 Sep 28 21:20 comp.c
>    -rw-rw-r-- 1 kail kail   37 Sep 28 21:20 comp.h
>    -rw-rw-r-- 1 kail kail 1248 Sep 28 21:22 comp.o
>    -rwxrwxr-x 1 kail kail 3241 Sep 28 21:22 main
>    -rwxrwxr-- 1 kail kail  137 Sep 28 21:20 main.c
>    -rw-rw-r-- 1 kail kail 1568 Sep 28 21:21 main.o

我丢失了什么吗?任何建议将不胜感激。谢谢!

3 个答案:

答案 0 :(得分:2)

您传递给--entry=main的参数ld没有按照您的想法行事。程序的入口点是程序启动的地方。但这不是main,它是在系统某处找到的目标文件_start中定义的名为crt0.o的函数。要手动链接C程序,请像这样调用ld

ld -o main main.o comp.o /path/to/crt0.o -lc

除非您知道它的作用,否则不要提供--entry

答案 1 :(得分:1)

当我尝试跑步时,我看到类似的东西:

-bash: ./main: /lib/ld64.so.1: bad ELF interpreter: No such file or directory

因此您可能无法正确调用ld。不要使用ld,而是使用gcc来调用它,因为它会处理您需要担心ld的详细信息。

gcc -c -o comp.o comp.c
gcc -c -o main.o main.c
gcc -o main main.o comp.o

答案 2 :(得分:1)

让我们看看gcc如何在详细模式下工作。

gcc -v -o main main.o comp.o

gcc使用以下命令链接对象

  

/usr/lib/gcc/x86_64-linux-gnu/4.4.3/collect2 --build-id --eh-frame-hdr   -m elf_x86_64 --hash-style = both -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o main -z relro   /usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../../lib/crt1.o   /usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../../lib/crti.o   /usr/lib/gcc/x86_64-linux-gnu/4.4.3/crtbegin.o   -L / usr / lib / gcc / x86_64-linux-gnu / 4.4.3 -L / usr / lib / gcc / x86_64-linux-gnu / 4.4.3 -L / usr / lib / gcc / x86_64-linux-gnu /4.4.3/../../../../lib -L ​​/ lib /../ lib -L ​​/ usr / lib /../ lib -L ​​/ usr / lib / gcc / x86_64-linux -gnu / 4.4.3 /../../ .. main.o comp.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc   --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-linux-gnu/4.4.3/crtend.o   /usr/lib/gcc/x86_64-linux-gnu/4.4.3 /../../../../ LIB / crtn.o

如果用 ld 替换/usr/lib/gcc/x86_64-linux-gnu/4.4.3/collect2,则链接过程会成功完成。

  

ld --build-id --eh-frame-hdr -m elf_x86_64 --hash-style = both   -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o main -z relro /usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../ ../lib/crt1.o   /usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../../lib/crti.o   /usr/lib/gcc/x86_64-linux-gnu/4.4.3/crtbegin.o   -L / usr / lib / gcc / x86_64-linux-gnu / 4.4.3 -L / usr / lib / gcc / x86_64-linux-gnu / 4.4.3 -L / usr / lib / gcc / x86_64-linux-gnu /4.4.3/../../../../lib -L ​​/ lib /../ lib -L ​​/ usr / lib /../ lib -L ​​/ usr / lib / gcc / x86_64-linux -gnu / 4.4.3 /../../ .. main.o comp.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc   --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-linux-gnu/4.4.3/crtend.o   /usr/lib/gcc/x86_64-linux-gnu/4.4.3 /../../../../ LIB / crtn.o

Refer this answer for further information