我正在尝试为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
这样的标准功能正常工作?
答案 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;
}
参数:argc
和argv
未使用,因此编译器将输出两个有关“未使用的参数”的警告语句。建议使用功能签名: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
看看会发生什么...。这将非常说明您系统中缺少什么。