在共享库中不使用PLT的情况下调用另一个目标文件中的函数? [英] Call a function in another object file without using PLT within a shared library?

查看:130
本文介绍了在共享库中不使用PLT的情况下调用另一个目标文件中的函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个汇编代码,code1.scode2.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时,出现myfun1relocation 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.soobjdump -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_auxregister_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源代码中有哪些系统调用,例如__chdirchdir.

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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆