没有源代码的.so文件的GCC链接

时间:2019-06-23 13:18:31

标签: c gcc cross-compiling ld uclibc

我正在尝试为Axis A210(cris体系结构)编译一个简单的“ hello world”程序。我设法从供应商那里下载了GCC,但glibc随附了该文件,并且相机正在运行uClibc-0.9.27。我从设备中提取了文件/lib/libuClibc-0.9.27.so

我设法编译了此段错误程序:

#include <unistd.h>

int main(int argc, char** argv)
{
    *((unsigned int*)0) = 0xDEAD;
}

和刚刚挂起的程序:

#include <unistd.h>

int main(int argc, char** argv)
{
    int a = 0;
}

带有cris-gcc -g -static -nostdlib -o compiled main.c

现在,我想使用libuClibc中的函数,但是我似乎无法正常工作:我已经尝试过

cris-gcc -g -static -nostdlib -o compiled main.c -luClibc-0.9.27 -L.

但这只是给出:

./libuClibc-0.9.27.so: could not read symbols: Invalid operation
collect2: ld returned 1 exit status

是否可以链接到该.so文件或以其他方式使诸如exit这样的标准功能正常工作?

2 个答案:

答案 0 :(得分:0)

关于:

cris-gcc -g -static -nostdlib -o compiled main.c -luClibc-0.9.27 -L.

链接器按照遇到库的顺序进行处理。因此,必须按所需顺序列出它们。

在知道要检查哪个库之前,链接器需要知道库的位置。建议:

cris-gcc -g -static -nostdlib -o compiled main.c -L.  -luClibc-0.9.27 

但是,*。so库不是静态库。它是一个动态库,因此应删除以下选项:-static但是,如果相关的* .a(静态库)可用,则要求动态库在“运行时”可用。在compile / link语句中使用。

注意:函数exit()的原型是通过stdlib.h头文件而不是unistd.h头文件公开的。

关于:

#include <unistd.h>

int main(int argc, char** argv)
{
    *((unsigned int*)0) = 0xDEAD;
}

参数:argcargv未使用,因此编译器将输出两个有关“未使用的参数”的警告语句。建议使用功能签名:int main( void )

此代码正在尝试写入地址0。但是,应用程序并不“拥有”地址0,(通常,该地址将被“标记”为“只读”,因此应用程序将以“ seg”退出故障事件')

包含头文件的那些内容未使用是不好的编程习惯。建议删除以下语句:#include <unistd.h>

此语句:int a = 0;将导致编译器输出有关已设置但从未使用过的变量的警告消息

关于:

cris-gcc -g -static -nostdlib -o compiled main.c -L. -luClibc-0.9.27

编译时,应始终启用警告,然后修复这些警告。建议:

cris-gcc -Wall -Wextra -Wconversion -pedantic -std=c99 -g -static -nostdlib -o compiled main.c -luClibc-0.9.27 -L.    

答案 1 :(得分:0)

@ user3629249在其答案中注意到的所有问题(都将被遵循)的一部分,消息:

./libuClibc-0.9.27.so: could not read symbols: Invalid operation
collect2: ld returned 1 exit status

意味着libuClibc-0.9.27.so二进制文件已被剥离其符号,或者您没有权限读取文件,因此没有符号表的权限。链接器无法使用该二进制文件,只能将其加载到内存中。无论如何,您需要一个非剥离的共享对象,并且如@ user3629249所建议,请勿使用-static(由于其回答中所述的原因),请按顺序放置参数(库目录之前 >要链接的库,也由他声明)。甚至您都可以通过将共享指定为以下链接来链接共享:

cris-gcc -nostdlib -o compiled main.c libluClibc-0.9.27.so

还有另一件事:您不仅需要标准的C库来链接可执行文件,还需要 ...通常,您需要在程序的开头使用crt0.o以及C运行时和程序的开始代码。您尚未包括在内,可能是编译器正在从另一个地方获取它。

一个问题:如果有了编译器,为什么要提供自己的标准库版本?编译器没有提供?如果更改libc,则还必须更改crt0.o文件。默认情况下是提供的某些编译器,您还没有收到消息no definition for start

尝试像以前一样仅使用主要函数进行编译,但不要指定共享库或目录,而只需指定主要代码:

cris-gcc -o compiled main.c

看看会发生什么...。这将非常说明您系统中缺少什么。