Call a function in another object file without using PLT within a shared library?

为君一笑 提交于 2020-01-23 20:10:16

问题


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.

I want code2.s call a function, named myfun1, which is defined in code1.s.

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.

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.

Here is my compile commands:

For codeX.s:

gcc -c codeX.s -fPIC -DPIC -o codeX.o

or

gcc -c codeX.s -o codeX.o

and for sharelibrary named libcodes.so:

gcc -shared -fPIC -DPIC -o libcodes.so code1.o code2.o

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.


回答1:


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.

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.


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.

Tested and working example:

## 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

Build with gcc -shared foo.S bar.S -o foo.so, and 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    

(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.)


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.

e.g. glibc's printf.c defines __printf and makes printf a strong alias for it.

io/chdir.c defines __chdir and makes chdir a weak alias for it.

One of the x86-64 memchr asm implementations also uses a strong_alias macro (at the bottom of the file).


The relevant GAS directives are:

  • .weak names
  • .weakref 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.)




回答2:


Well, I was not able to find any way to do so but as I edited my question I do not care to put myfun1 in all object files.

The problem I had was that linker outputted error that I have defined myfun1 in multiple places and that was all because I had globl directive for myfun1 which when I removed that line it get fixed.

Thanks Ross Ridge for pushing me again to try that.



来源:https://stackoverflow.com/questions/51573771/call-a-function-in-another-object-file-without-using-plt-within-a-shared-library

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!