C 如何在动态链接库中引用全局变量?
环境是32位SPARC上的Solaris,但我认为这是动态链接和/或位置独立代码的一个更普遍的问题 我有一个汇编程序,我编译为独立于位置的代码,并从C程序动态链接到它。它工作正常,只是我不能从汇编程序中引用汇编程序保留的任何内存。在汇编程序中跳转工作正常 我只想在汇编程序中读写内存,但每次尝试都会出现分段错误 我编写这个测试程序是为了调试这个问题C 如何在动态链接库中引用全局变量?,c,assembly,solaris,dynamic-linking,sparc,C,Assembly,Solaris,Dynamic Linking,Sparc,环境是32位SPARC上的Solaris,但我认为这是动态链接和/或位置独立代码的一个更普遍的问题 我有一个汇编程序,我编译为独立于位置的代码,并从C程序动态链接到它。它工作正常,只是我不能从汇编程序中引用汇编程序保留的任何内存。在汇编程序中跳转工作正常 我只想在汇编程序中读写内存,但每次尝试都会出现分段错误 我编写这个测试程序是为了调试这个问题 .section ".data" .global foo foo: .word 1 .section ".text" .global
.section ".data"
.global foo
foo: .word 1
.section ".text"
.global testprog
testprog:
save %sp, -(92+4), %sp
sethi %hi(foo), %o0 ! set foo, %o0
or %o0, %lo(foo), %o0
call print_int
nop
ret
restore
我把它编译成
as-K PIC-b
然后打开结果。在C中也是如此
dlhandle = dlopen(obj_file, RTLD_NOW)
dl_testprog = dlsym(dlhandle, "testprog")
当我调用dl_testprog()
时,它会打印“4”。如果我试图打印testprog或print_int的地址,它也会打印“4”。跳转到标签,其他一切都可以正常工作。在反汇编中,foo被0x0替换,这是应该的
我是否必须通过
\u GLOBAL\u OFFSET\u TABLE\u
或其他程序,才能在汇编程序中写入自己的内存?如果是,我该怎么做?我尝试的每件事都导致了一个SEGFULT,我还没有找到一个很好的指南如何做到这一点(这让我相信你不应该这么做。这不是链接器的问题吗?)。是的,我相信你必须通过访问才能处理私人数据。见第9.2节。尽管NASM是x86汇编程序,但在SPARC/Solaris上的一般原则也应该相同
此外,AT&T汇编程序通常使用“@got”语法来指定重新定位wrt。得到了。确切的细节将在您的汇编程序手册中描述,即NASM的语法细节将不适用于Solaris的汇编程序。通过查看C编译器为PIC输出的代码解决了这个问题,这是我从一开始就应该做的,而不是阅读手册和随机网页 也许这是显而易见的,但实际上PIC中一个对象的真实地址(至少在32b SPARC上)是(
\u GLOBAL\u OFFSET\u TABLE\u+PC+object
)。约定是在函数开头计算到%l7的GET地址。除了如何实际计算%l7之外,详细信息如下所示
addpc:
add %o7, %l7, %l7 ! %o7 == addr of call == PC
retl
nop
testprog:
sethi %hi(_GLOBAL_OFFSET_TABLE_-8), %l7 ! -8 = distance from call addpc
add %l7, %lo(_GLOBAL_OFFSET_TABLE_-4), %l7
call addpc ! add PC to %l7
nop
+1查看C汇编输出:-)(几年前帮助我在m68k上编写了一个非常快速和优化的中断处理程序。我只是在C中启动它,获取ASM输出并对其进行优化…在该项目之前没有为m68k编写汇编程序)。