ham*_*ari 6 c function-pointers dynamic-linking linux-toolchain avr32
我遇到了一个奇怪的情况,即执行涉及动态链接符号的指针算法会导致错误的结果.我不确定是否只是缺少一些链接器参数或者它是否是链接器错误.有人能解释下面的例子中有什么问题吗?
考虑以下lib.c简单共享库的代码():
#include <inttypes.h>
#include <stdio.h>
uintptr_t getmask()
{
return 0xffffffff;
}
int fn1()
{
return 42;
}
void fn2()
{
uintptr_t mask;
uintptr_t p;
mask = getmask();
p = (uintptr_t)fn1 & mask;
printf("mask: %08x\n", mask);
printf("fn1: %p\n", fn1);
printf("p: %08x\n", p);
}
Run Code Online (Sandbox Code Playgroud)
有问题的操作是地址fn1和变量之间的按位AND mask.application(app.c)只是这样调用fn2:
extern int fn2();
int main()
{
fn2();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它导致以下输出......
mask: ffffffff
fn1: 0x2aab43c0
p: 000003c0
Run Code Online (Sandbox Code Playgroud)
......这显然是不正确的,因为预期fn1
和的结果相同p.代码在AVR32架构上运行,编译如下:
$ avr32-linux-uclibc-gcc -Os -Wextra -Wall -c -o lib.o lib.c
$ avr32-linux-uclibc-gcc -Os -Wextra -Wall -shared -o libfoo.so lib.o
$ avr32-linux-uclibc-gcc -Os -Wextra -Wall -o app app.c -L. -lfoo
Run Code Online (Sandbox Code Playgroud)
编译器认为,将变量加载mask到32位寄存器7并将&-operation分成两个具有立即操作数的汇编操作是最佳解决方案
.
$ avr32-linux-uclibc-objdump -d libfoo.so
000003ce <fn1>:
3ce: 32 ac mov r12,42
3d0: 5e fc retal r12
000003d2 <fn2>:
...
3f0: e4 17 00 00 andh r7,0x0
3f4: e0 17 03 ce andl r7,0x3ce
Run Code Online (Sandbox Code Playgroud)
我假设and指令的立即操作数不会重定位到fn1共享库加载到应用程序地址空间时的加载地址:
背景:这不是学术问题.OpenSSL和LibreSSL使用类似的代码,因此不能更改C源代码.代码在其他体系结构上运行良好,当然在函数指针上进行按位运算有一个不明显的原因.
纠正代码中的所有“错误”后,结果是:
#include <inttypes.h>
#include <stdio.h>
int fn1( void );
void fn2( void );
uintptr_t getmask( void );
int main( void )
{
fn2();
return 0;
}
uintptr_t getmask()
{
return 0xffffffff;
}
int fn1()
{
return 42;
}
void fn2()
{
uintptr_t mask;
uintptr_t p;
mask = getmask();
p = (uintptr_t)fn1 & mask;
printf("mask: %08x\n", (unsigned int)mask);
printf("fn1: %p\n", fn1);
printf("p: %08x\n", (unsigned int)p);
}
Run Code Online (Sandbox Code Playgroud)
输出(在我的 linux 64 位计算机上)是:
mask: ffffffff
fn1: 0x4007c1
p: 004007c1
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
175 次 |
| 最近记录: |