1

我正在尝试为 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工作?

4

2 回答 2

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 (静态库)可用,则要求动态库在“运行时”可用,那么它应该在编译/链接声明。

注意:函数:exit()通过stdlib.h头文件而不是unistd.h头文件暴露其原型。

关于:

#include <unistd.h>

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

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

此代码正在尝试写入地址 0。但是,应用程序并不“拥有”地址 0,(通常,这样的地址将被“标记”为“只读”,因此应用程序将退出并出现“段错误事件” )

包含那些内容未被使用的头文件是一种糟糕的编程习惯。建议删除语句:#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.    
于 2019-06-23T15:14:08.967 回答
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在程序开头使用 a 与 C 运行时和程序的启动代码。您没有包含它,并且可能编译器是从另一个地方获取它的。

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

尝试仅使用 main 函数进行编译,就像您所做的那样,但不要指定共享库或目录......只是主要代码:

cris-gcc -o compiled main.c

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

于 2019-06-25T07:39:48.830 回答