我正在尝试为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
这样的标准函数正常工作?
发布于 2019-06-23 23:14:09
关于:
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 (静态库)可用,则应在编译/链接语句中使用它。
注意:函数: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 (通常,这样的地址将被“标记”为“readonly”,因此应用程序将退出并返回“seg event event”)
包含未使用的头文件是一种糟糕的编程实践。建议删除语句:#include <unistd.h>
此语句:int a = 0;
将导致编译器输出有关变量的警告消息,该变量是'set‘但从未'used’
关于:
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.
发布于 2019-06-25 15:39:49
除了@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
。
尝试只使用main函数进行编译,就像您所做的那样,但不要指定共享库或目录……只有主要代码:
cris-gcc -o compiled main.c
看看会发生什么.这将非常说明您的系统中所缺少的内容。
https://stackoverflow.com/questions/56724268
复制相似问题