使用链接器构建程序,但 运行 可执行文件显示 'No such file or directory'

Use linker to build program but run executable shows 'No such file or directory'

我写了一个包含两个文件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

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

当我尝试 运行:

时,我看到了类似的东西
-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

您传递给 ld 的参数 --entry=main 与您认为的不符。程序的入口点是程序开始的地方。不过,这不是 main,它是一个名为 _start 的函数,定义在您系统某处的对象文件 crt0.o 中。要手动 link C 程序,请像这样调用 ld

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

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

让我们看看 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

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

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