在共享库中不使用PLT的情况下调用另一个目标文件中的函数? [英] Call a function in another object file without using PLT within a shared library?
问题描述
我有两个汇编代码,code1.s
和code2.s
,我想从这两个代码中构建一个可重定位的共享库(使用-fPIC开关).
I have two assembly codes, code1.s
and code2.s
and I want to build a relocatable (using -fPIC switch) shared library from these two.
我想code2.s
调用一个名为myfun1
的函数,该函数在code1.s
中定义.
I want code2.s
call a function, named myfun1
, which is defined in code1.s
.
当我在code2.s
中使用call myfun1@PLT
时,它找到了该函数,并且像一个超级按钮一样工作,但是它使用PLT节来调用此函数,该函数位于同一共享库中.我不想遵循PLT部分来执行此操作.删除@PLT
时,出现myfun1
的relocation R_X86_64_PC32 against symbol
错误.
When I use call myfun1@PLT
in code2.s
it finds the function and it works like a charm but it uses PLT section to call this function which is in the same shared library. I want to do this without adhering to PLT section. When I remove @PLT
I get the relocation R_X86_64_PC32 against symbol
error for myfun1
.
如何在不使用PLT部分的情况下执行此操作?有什么办法吗?我认为这是可行的,因为共享库应该可重定位,但不必每个对象文件都在其中,因此,为什么在同一个库中调用函数应该通过PLT部分.
How can I do this without using PLT section? Is there any way at all? I think it should be feasible as the shared library should be relocatable but not necessary each of its object files, therefore why calling a function inside the same library should goes through the PLT section.
这是我的编译命令:
对于codeX.s:
gcc -c codeX.s -fPIC -DPIC -o codeX.o
或
gcc -c codeX.s -o codeX.o
以及对于名为libcodes.so的共享库:
and for sharelibrary named libcodes.so:
gcc -shared -fPIC -DPIC -o libcodes.so code1.o code2.o
正如您可能好奇为什么这样做的那样,我有很多目标文件,并且每个文件都想调用myfun1
.在这里,我只是简单地询问了技术部分.甚至我尝试将myfun1
放入所有codeX.s
文件中,但我收到错误,多次定义了myfun1
.我不太在乎空间以及是否要在所有文件中放入myfun1
.
Just as you may be curious why I am doing so, I have many object files and each of them wants to call myfun1
. Here I just made it simpler to ask the technical part. Even I tries to put myfun1
in all codeX.s
files but I get the error that myfun1
is defined multiple times. I don't that much care about space and if I get to put myfun1
in all files.
推荐答案
From within one source file you can just use two labels (Building .so with recursive function in it), one with .globl
and the other not. But that's not sufficient across source files within the shared library.
与下面的答案结合使用对于仍要导出的功能仍然很有用:一个.hidden而不是一个,因此您可以在库中高效调用.
Still useful in combination with the below answer for functions that are also exported: one .hidden and one not, so you can efficiently call within the library.
使用.globl
和 .hidden
创建可以在当前目标文件外部看到的符号,但是在共享库外部不能看到的符号.因此,它不受符号插入的限制,并且来自同一共享库中其他文件的调用可以直接调用,而不是通过PLT或GOT调用.
Use .globl
and .hidden
to create a symbol that can be seen outside the current object file, but not outside the shared library. Thus it's not subject to symbol-interposition, and calls from other files in the same shared library can call it directly, not through the PLT or GOT.
经过测试的有效示例:
## foo.S
.globl myfunc
.hidden myfunc
myfunc:
#.globl myfunc_external # optional, a non-hidden symbol at the same addr
#myfunc_external:
ret
## bar.S
.globl bar
bar:
call myfunc
ret
使用gcc -shared foo.S bar.S -o foo.so
和objdump -drwC -Mintel foo.so
构建:
Disassembly of section .text:
000000000000024d <myfunc>:
24d: c3 ret
000000000000024e <bar>:
24e: e8 fa ff ff ff call 24d <myfunc> # a direct near call
253: c3 ret
(我实际上还使用-nostdlib
进行构建,通过省略其他功能,例如__do_global_dtors_aux
和register_tm_clones
以及.init
部分,以保持反汇编输出的清洁.)
(I actually built with -nostdlib
as well to keep the disassembly output clean for example purposes by omitting the other functions like __do_global_dtors_aux
and register_tm_clones
, and the .init
section.)
我认为Glibc为此使用了强或weak_alias
(在glibc源代码中有哪些系统调用,例如__chdir
和chdir
.
I think Glibc uses strong or weak_alias
for this (what does the weak_alias function do and where is it defined), so calls from within the shared library can use the normal name. Where are syscalls located in glibc source, e.g. __chdir
and chdir
.
例如 glibc的printf.c
定义了__printf
并使printf
一个 strong 别名.
io/chdir.c
定义__chdir
并使chdir
为其 weak 的别名.
其中一种x86-64 memchr asm实现也使用strong_alias
宏(在文件底部).
One of the x86-64 memchr asm implementations also uses a strong_alias
macro (at the bottom of the file).
相关的GAS指令为:
没有强大的别名GAS指令.这可能等效于foo = foo_internal
或等效的.set foo, foo_internal
.
There's no strong alias GAS directive. That may be equivalent to simply foo = foo_internal
or an equivalent .set foo, foo_internal
.
(待办事项:完整的示例以及关于强/弱的确切功能的更多详细信息.我目前尚不知道,因此如果我不愿意自己阅读文档,欢迎进行编辑. 我知道这些东西存在并且可以解决此问题,但是我不知道具体如何.)
(TODO: complete example and more details of what strong/weak do exactly. I don't currently know, so edits welcome if I don't get around to reading the docs myself. I know this stuff exists and solves this problem, but I don't know exactly how.)
这篇关于在共享库中不使用PLT的情况下调用另一个目标文件中的函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!